Merge branch 'master' of https://github.com/kivitendo/kivitendo-erp
authorNiclas Zimmermann <niclas@kivitendo-premium.de>
Thu, 18 Jul 2013 07:30:28 +0000 (09:30 +0200)
committerNiclas Zimmermann <niclas@kivitendo-premium.de>
Thu, 18 Jul 2013 07:30:28 +0000 (09:30 +0200)
156 files changed:
SL/AP.pm
SL/Controller/Admin.pm
SL/Controller/Customer.pm [deleted file]
SL/Controller/CustomerVendor.pm [new file with mode: 0644]
SL/Controller/DeliveryPlan.pm
SL/Controller/Inventory.pm
SL/Controller/LoginScreen.pm
SL/Controller/SellPriceInformation.pm
SL/DB/CustomVariable.pm
SL/DB/CustomVariableConfig.pm
SL/DB/Helper/CustomVariables.pm
SL/DB/Manager/AuthClient.pm
SL/DB/Note.pm
SL/FU.pm
SL/Form.pm
SL/InstanceConfiguration.pm
SL/Layout/Admin.pm
SL/Layout/Base.pm
SL/Layout/Javascript.pm
SL/Layout/V3.pm
SL/Menu.pm
SL/Presenter/CustomerVendor.pm
SL/Template/Plugin/JavaScript.pm
bin/mozilla/ct.pl
bin/mozilla/wh.pl
doc/changelog
image/icons/16x16/CRM--Add--Customer.png [new file with mode: 0644]
image/icons/16x16/CRM--Add--Person.png [new file with mode: 0644]
image/icons/16x16/CRM--Add--Vendor.png [new file with mode: 0644]
image/icons/16x16/CRM--Admin--Benutzer.png [deleted file]
image/icons/16x16/CRM--Admin--Document Template.png [new file with mode: 0644]
image/icons/16x16/CRM--Admin--Dokumentvorlage.png [deleted file]
image/icons/16x16/CRM--Admin--Etiketten.png [deleted file]
image/icons/16x16/CRM--Admin--Gruppen.png [deleted file]
image/icons/16x16/CRM--Admin--Label.png [new file with mode: 0644]
image/icons/16x16/CRM--Admin--Message.png [new file with mode: 0644]
image/icons/16x16/CRM--Admin--Mitteilungen.png [deleted file]
image/icons/16x16/CRM--Admin--User Groups.png [new file with mode: 0644]
image/icons/16x16/CRM--Admin--User.png [new file with mode: 0644]
image/icons/16x16/CRM--Appointments.png [new file with mode: 0644]
image/icons/16x16/CRM--Auftragschance.png [deleted file]
image/icons/16x16/CRM--E-mail.png [new file with mode: 0644]
image/icons/16x16/CRM--Follow-Up.png [new file with mode: 0644]
image/icons/16x16/CRM--Help.png [new file with mode: 0644]
image/icons/16x16/CRM--Hilfe.png [deleted file]
image/icons/16x16/CRM--Knowledge.png [new file with mode: 0644]
image/icons/16x16/CRM--Kunden.png [deleted file]
image/icons/16x16/CRM--Lieferant.png [deleted file]
image/icons/16x16/CRM--Memo.png [new file with mode: 0644]
image/icons/16x16/CRM--Notizen.png [deleted file]
image/icons/16x16/CRM--Opportunity.png [new file with mode: 0644]
image/icons/16x16/CRM--Personen.png [deleted file]
image/icons/16x16/CRM--Schnellsuche.png [deleted file]
image/icons/16x16/CRM--Search.png [new file with mode: 0644]
image/icons/16x16/CRM--Termine.png [deleted file]
image/icons/16x16/CRM--Wiedervorlage.png [deleted file]
image/icons/16x16/CRM--Wissens-DB.png [deleted file]
image/icons/16x16/CRM--eMail.png [deleted file]
image/icons/24x24/CRM--Add--Customer.png [new file with mode: 0644]
image/icons/24x24/CRM--Add--Person.png [new file with mode: 0644]
image/icons/24x24/CRM--Add--Vendor.png [new file with mode: 0644]
image/icons/24x24/CRM--Admin--Benutzer.png [deleted file]
image/icons/24x24/CRM--Admin--Document Template.png [new file with mode: 0644]
image/icons/24x24/CRM--Admin--Dokumentvorlage.png [deleted file]
image/icons/24x24/CRM--Admin--Etiketten.png [deleted file]
image/icons/24x24/CRM--Admin--Gruppen.png [deleted file]
image/icons/24x24/CRM--Admin--Label.png [new file with mode: 0644]
image/icons/24x24/CRM--Admin--Message.png [new file with mode: 0644]
image/icons/24x24/CRM--Admin--Mitteilungen.png [deleted file]
image/icons/24x24/CRM--Admin--User Groups.png [new file with mode: 0644]
image/icons/24x24/CRM--Admin--User.png [new file with mode: 0644]
image/icons/24x24/CRM--Appointments.png [new file with mode: 0644]
image/icons/24x24/CRM--Auftragschance.png [deleted file]
image/icons/24x24/CRM--Follow-Up.png [new file with mode: 0644]
image/icons/24x24/CRM--Help.png [new file with mode: 0644]
image/icons/24x24/CRM--Hilfe.png [deleted file]
image/icons/24x24/CRM--Knowledge.png [new file with mode: 0644]
image/icons/24x24/CRM--Kunden.png [deleted file]
image/icons/24x24/CRM--Lieferant.png [deleted file]
image/icons/24x24/CRM--Memo.png [new file with mode: 0644]
image/icons/24x24/CRM--Notizen.png [deleted file]
image/icons/24x24/CRM--Opportunity.png [new file with mode: 0644]
image/icons/24x24/CRM--Personen.png [deleted file]
image/icons/24x24/CRM--Schnellsuche.png [deleted file]
image/icons/24x24/CRM--Search.png [new file with mode: 0644]
image/icons/24x24/CRM--Termine.png [deleted file]
image/icons/24x24/CRM--Wiedervorlage.png [deleted file]
image/icons/24x24/CRM--Wissens-DB.png [deleted file]
image/icons/32x32/CRM--Add--Customer.png [new file with mode: 0644]
image/icons/32x32/CRM--Add--Person.png [new file with mode: 0644]
image/icons/32x32/CRM--Add--Vendor.png [new file with mode: 0644]
image/icons/32x32/CRM--Admin--Benutzer.png [deleted file]
image/icons/32x32/CRM--Admin--Document Template.png [new file with mode: 0644]
image/icons/32x32/CRM--Admin--Dokumentvorlage.png [deleted file]
image/icons/32x32/CRM--Admin--Etiketten.png [deleted file]
image/icons/32x32/CRM--Admin--Gruppen.png [deleted file]
image/icons/32x32/CRM--Admin--Label.png [new file with mode: 0644]
image/icons/32x32/CRM--Admin--Message.png [new file with mode: 0644]
image/icons/32x32/CRM--Admin--Mitteilungen.png [deleted file]
image/icons/32x32/CRM--Admin--User Groups.png [new file with mode: 0644]
image/icons/32x32/CRM--Admin--User.png [new file with mode: 0644]
image/icons/32x32/CRM--Appointments.png [new file with mode: 0644]
image/icons/32x32/CRM--Auftragschance.png [deleted file]
image/icons/32x32/CRM--Follow-Up.png [new file with mode: 0644]
image/icons/32x32/CRM--Help.png [new file with mode: 0644]
image/icons/32x32/CRM--Hilfe.png [deleted file]
image/icons/32x32/CRM--Knowledge.png [new file with mode: 0644]
image/icons/32x32/CRM--Kunden.png [deleted file]
image/icons/32x32/CRM--Lieferant.png [deleted file]
image/icons/32x32/CRM--Memo.png [new file with mode: 0644]
image/icons/32x32/CRM--Notizen.png [deleted file]
image/icons/32x32/CRM--Opportunity.png [new file with mode: 0644]
image/icons/32x32/CRM--Personen.png [deleted file]
image/icons/32x32/CRM--Schnellsuche.png [deleted file]
image/icons/32x32/CRM--Search.png [new file with mode: 0644]
image/icons/32x32/CRM--Termine.png [deleted file]
image/icons/32x32/CRM--Wiedervorlage.png [deleted file]
image/icons/32x32/CRM--Wissens-DB.png [deleted file]
js/autocomplete_customer.js
js/autocomplete_part.js
js/common.js
js/kivi.CustomerVendor.js [new file with mode: 0644]
js/locale/de.js
locale/de/all
locale/en/all
menu.ini [deleted file]
menus/admin.ini [new file with mode: 0644]
menus/crm.ini [new file with mode: 0644]
menus/erp.ini [new file with mode: 0644]
scripts/locales.pl
sql/Pg-upgrade2/SKR04-3804-addition.pl
templates/webpages/admin/create_dataset.html
templates/webpages/admin/dbadmin.html
templates/webpages/admin/delete_dataset.html
templates/webpages/admin/edit_client.html
templates/webpages/admin/edit_group.html
templates/webpages/admin/edit_printer.html
templates/webpages/admin/edit_user.html
templates/webpages/admin/list_printers.html
templates/webpages/admin/show.html
templates/webpages/admin/show_lock.html [new file with mode: 0644]
templates/webpages/ct/ajax_autocomplete2.json [deleted file]
templates/webpages/customer_vendor/form.html [new file with mode: 0644]
templates/webpages/customer_vendor/get_delivery.html [new file with mode: 0644]
templates/webpages/customer_vendor/render_cvar_input.html [new file with mode: 0644]
templates/webpages/customer_vendor/tabs/billing.html [new file with mode: 0644]
templates/webpages/customer_vendor/tabs/contacts.html [new file with mode: 0644]
templates/webpages/customer_vendor/tabs/custom_variables.html [new file with mode: 0644]
templates/webpages/customer_vendor/tabs/deliveries.html [new file with mode: 0644]
templates/webpages/customer_vendor/tabs/shipto.html [new file with mode: 0644]
templates/webpages/customer_vendor/tabs/vcnotes.html [new file with mode: 0644]
templates/webpages/inventory/_stock.html
templates/webpages/menu/menuv3.html
templates/webpages/part/part_picker_search.html
templates/webpages/sepa/bank_transfer_add.html
templates/webpages/sepa/bank_transfer_create.html

index 7a148d6..f754137 100644 (file)
--- a/SL/AP.pm
+++ b/SL/AP.pm
@@ -371,7 +371,7 @@ sub post_transaction {
         $query =
           qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate, fx_transaction, cleared, project_id, taxkey, tax_id, chart_link) | .
           qq|VALUES (?, (SELECT id FROM chart WHERE accno = ?), ?, ?, 't', 'f', ?, | .
-          qq|        (SELECT taxkey_id FROM chart WHERE accno = ?)| .
+          qq|        (SELECT taxkey_id FROM chart WHERE accno = ?),| .
           qq|        (SELECT tax_id| .
           qq|         FROM taxkeys| .
           qq|         WHERE chart_id= (SELECT id | .
@@ -878,4 +878,3 @@ sub storno {
 }
 
 1;
-
index bcc9436..698fdb1 100644 (file)
@@ -378,16 +378,13 @@ sub action_delete_printer {
 # actions: database administration
 #
 
-sub action_database_administration {
+sub action_create_dataset_login {
   my ($self) = @_;
 
-  $::form->{dbhost}    ||= $::auth->{DB_config}->{host} || 'localhost';
-  $::form->{dbport}    ||= $::auth->{DB_config}->{port} || 5432;
-  $::form->{dbuser}    ||= $::auth->{DB_config}->{user} || 'kivitendo';
-  $::form->{dbpasswd}  ||= $::auth->{DB_config}->{password};
-  $::form->{dbdefault} ||= 'template1';
-
-  $self->render('admin/dbadmin', title => t8('Database Administration'));
+  $self->database_administration_login_form(
+    title       => t8('Create Dataset'),
+    next_action => 'create_dataset',
+  );
 }
 
 sub action_create_dataset {
@@ -414,6 +411,15 @@ sub action_do_create_dataset {
   $self->redirect_to(action => 'database_administration');
 }
 
+sub action_delete_dataset_login {
+  my ($self) = @_;
+
+  $self->database_administration_login_form(
+    title       => t8('Delete Dataset'),
+    next_action => 'delete_dataset',
+  );
+}
+
 sub action_delete_dataset {
   my ($self) = @_;
   $self->delete_dataset_form;
@@ -440,6 +446,15 @@ sub action_do_delete_dataset {
 # actions: locking, unlocking
 #
 
+sub action_show_lock {
+  my ($self) = @_;
+
+  $self->render(
+    "admin/show_lock",
+    title => "kivitendo " . t8('Administration'),
+  );
+}
+
 sub action_unlock_system {
   my ($self) = @_;
 
@@ -451,7 +466,7 @@ sub action_unlock_system {
 sub action_lock_system {
   my ($self) = @_;
 
-  SL::System::InstallationLock->unlock;
+  SL::System::InstallationLock->lock;
   flash_later('info', t8('Lockfile created!'));
   $self->redirect_to(action => 'show');
 }
@@ -532,7 +547,6 @@ sub setup_layout {
   my ($self, $action) = @_;
 
   $::request->layout(SL::Layout::Dispatcher->new(style => 'admin'));
-  $::request->layout->use_stylesheet("lx-office-erp.css");
   $::form->{favicon} = "favicon.ico";
   %::myconfig        = (
     countrycode      => 'de',
@@ -544,11 +558,10 @@ sub setup_layout {
 sub setup_client {
   my ($self) = @_;
 
-  $self->client((first { $_->is_default } @{ $self->all_clients }) || $self->all_clients->[0]) if !$self->client;
+  $self->client(SL::DB::Manager::AuthClient->get_default || $self->all_clients->[0]) if !$self->client;
   $::auth->set_client($self->client->id);
 }
 
-
 #
 # displaying forms
 #
@@ -563,6 +576,7 @@ sub use_multiselect_js {
 sub login_form {
   my ($self, %params) = @_;
   my $version         = $::form->read_version;
+  $::request->layout->no_menu(1);
   $self->render('admin/adminlogin', title => t8('kivitendo v#1 administration', $version), %params, version => $version);
 }
 
@@ -586,6 +600,20 @@ sub edit_printer_form {
   $self->render('admin/edit_printer', %params);
 }
 
+sub database_administration_login_form {
+  my ($self, %params) = @_;
+
+  $self->render(
+    'admin/dbadmin',
+    dbhost    => $::form->{dbhost}    || $::auth->{DB_config}->{host} || 'localhost',
+    dbport    => $::form->{dbport}    || $::auth->{DB_config}->{port} || 5432,
+    dbuser    => $::form->{dbuser}    || $::auth->{DB_config}->{user} || 'kivitendo',
+    dbpasswd  => $::form->{dbpasswd}  || $::auth->{DB_config}->{password},
+    dbdefault => $::form->{dbdefault} || 'template1',
+    %params,
+  );
+}
+
 sub create_dataset_form {
   my ($self, %params) = @_;
   $self->render('admin/create_dataset', title => (t8('Database Administration') . " / " . t8('Create Dataset')));
diff --git a/SL/Controller/Customer.pm b/SL/Controller/Customer.pm
deleted file mode 100644 (file)
index 823af2e..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-package SL::Controller::Customer;
-
-use strict;
-use parent qw(SL::Controller::Base);
-
-use SL::DB::Customer;
-
-# safety
-__PACKAGE__->run_before(sub { $::auth->assert('customer_vendor_edit') });
-
-sub action_ajax_autocomplete {
-  my ($self, %params) = @_;
-
-  my $limit  = $::form->{limit}  || 20;
-  my $type   = $::form->{type} || {};
-  my $query  = { ilike => "%$::form->{term}%" };
-  my @filter;
-  push @filter, ($::form->{column})
-    ? ($::form->{column} => $query)
-    : (or => [ customernumber => $query, name => $query ]);
-
-  $self->{customers} = SL::DB::Manager::Customer->get_all(query => [ @filter ], limit => $limit);
-  $self->{value} = $::form->{column} || 'name';
-
-  $self->render('ct/ajax_autocomplete2', { layout => 0, type => 'json' });
-}
diff --git a/SL/Controller/CustomerVendor.pm b/SL/Controller/CustomerVendor.pm
new file mode 100644 (file)
index 0000000..cfe7acc
--- /dev/null
@@ -0,0 +1,777 @@
+package SL::Controller::CustomerVendor;
+
+use strict;
+use parent qw(SL::Controller::Base);
+
+use SL::JSON;
+use SL::DBUtils;
+use SL::Helper::Flash;
+
+use SL::DB::Customer;
+use SL::DB::Vendor;
+use SL::DB::Business;
+use SL::DB::Employee;
+use SL::DB::Language;
+use SL::DB::TaxZone;
+use SL::DB::Note;
+use SL::DB::PaymentTerm;
+use SL::DB::Pricegroup;
+use SL::DB::Contact;
+use SL::DB::FollowUp;
+use SL::DB::History;
+use SL::DB::Currency;
+
+# safety
+__PACKAGE__->run_before(
+  sub {
+    $::auth->assert('customer_vendor_edit');
+  }
+);
+
+__PACKAGE__->run_before(
+  '_instantiate_args',
+  only => [
+    'save',
+    'save_and_ap_transaction',
+    'save_and_ar_transaction',
+    'save_and_close',
+    'save_and_invoice',
+    'save_and_order',
+    'save_and_quotation',
+    'save_and_rfq',
+    'delete',
+    'delete_contact',
+    'delete_shipto',
+  ]
+);
+
+__PACKAGE__->run_before(
+  '_load_customer_vendor',
+  only => [
+    'edit',
+    'update',
+    'ajaj_get_shipto',
+    'ajaj_get_contact',
+  ]
+);
+__PACKAGE__->run_before(
+  '_create_customer_vendor',
+  only => [
+    'add',
+  ]
+);
+
+sub action_add {
+  my ($self) = @_;
+
+  $self->_pre_render();
+  $self->render(
+    'customer_vendor/form',
+    title => ($self->is_vendor() ? $::locale->text('Add Vendor') : $::locale->text('Add Customer')),
+    %{$self->{template_args}}
+  );
+}
+
+sub action_edit {
+  my ($self) = @_;
+
+  $self->_pre_render();
+  $self->render(
+    'customer_vendor/form',
+    title => ($self->is_vendor() ? $::locale->text('Edit Vendor') : $::locale->text('Edit Customer')),
+    %{$self->{template_args}}
+  );
+}
+
+sub _save {
+  my ($self) = @_;
+
+  my $db = $self->{cv}->db;
+
+  $db->do_transaction(sub {
+    my $cvs_by_nr;
+    if ( $self->is_vendor() ) {
+      if ( $self->{cv}->vendornumber ) {
+        $cvs_by_nr = SL::DB::Manager::Vendor->get_all(query => [vendornumber => $self->{cv}->vendornumber]);
+      }
+    } else {
+      if ( $self->{cv}->customernumber ) {
+        $cvs_by_nr = SL::DB::Manager::Customer->get_all(query => [customernumber => $self->{cv}->customernumber]);
+      }
+    }
+
+    foreach my $entry (@{$cvs_by_nr}) {
+      if( $entry->id != $self->{cv}->id ) {
+        my $msg =
+          $self->is_vendor() ? $::locale->text('This vendor number is already in use.') : $::locale->text('This customer number is already in use.');
+
+        $::form->error($msg);
+      }
+    }
+
+    $self->{cv}->save(cascade => 1);
+
+    $self->{contact}->cp_cv_id($self->{cv}->id);
+    if( $self->{contact}->cp_name ne '' || $self->{contact}->cp_givenname ne '' ) {
+      $self->{contact}->save();
+    }
+
+    if( $self->{note}->subject ne '' && $self->{note}->body ne '' ) {
+      $self->{note}->trans_id($self->{cv}->id);
+      $self->{note}->save();
+      $self->{note_followup}->save();
+
+      $self->{note} = SL::DB::Note->new();
+      $self->{note_followup} = SL::DB::FollowUp->new();
+    }
+
+    $self->{shipto}->trans_id($self->{cv}->id);
+    if( $self->{shipto}->shiptoname ne '' ) {
+      $self->{shipto}->save();
+    }
+
+    my $snumbers = $self->is_vendor() ? 'vendornumber_'. $self->{cv}->vendornumber : 'customernumber_'. $self->{cv}->customernumber;
+    SL::DB::History->new(
+      trans_id => $self->{cv}->id,
+      snumbers => $snumbers,
+      employee_id => SL::DB::Manager::Employee->current->id,
+      addition => 'SAVED',
+    )->save();
+  }) || die($db->error);
+
+}
+
+sub action_save {
+  my ($self) = @_;
+
+  $self->_save();
+
+  $self->redirect_to(action => 'edit', id => $self->{cv}->id, db => $self->is_vendor() ? 'vendor' : 'customer');
+}
+
+sub action_save_and_close {
+  my ($self) = @_;
+
+  $self->_save();
+
+  my $msg = $self->is_vendor() ? $::locale->text('Vendor saved') : $::locale->text('Customer saved');
+  $::form->redirect($msg);
+}
+
+sub _transaction {
+  my ($self, $script) = @_;
+
+  $::auth->assert('general_ledger         | invoice_edit         | vendor_invoice_edit | ' .
+                 ' request_quotation_edit | sales_quotation_edit | sales_order_edit    | purchase_order_edit');
+
+  $self->_save();
+
+  my $callback = $::form->escape($::form->{callback}, 1);
+  my $name = $::form->escape($self->{cv}->name, 1);
+  my $db = $self->is_vendor() ? 'vendor' : 'customer';
+
+  my $url = $self->url_for(
+    controller => $script,
+    action     => 'add',
+    vc         => $db,
+    $db .'_id' => $self->{cv}->id,
+    $db        => $name,
+    type       => $::form->{type},
+    callback   => $callback,
+  );
+
+  print $::form->redirect_header($url);
+}
+
+sub action_save_and_ar_transaction {
+  my ($self) = @_;
+
+  $main::auth->assert('general_ledger');
+
+  $self->_transaction('ar.pl');
+}
+
+sub action_save_and_ap_transaction {
+  my ($self) = @_;
+
+  $main::auth->assert('general_ledger');
+
+  $self->_transaction('ap.pl');
+}
+
+sub action_save_and_invoice {
+  my ($self) = @_;
+
+  if ( $self->is_vendor() ) {
+    $::auth->assert('vendor_invoice_edit');
+  } else {
+    $::auth->assert('invoice_edit');
+  }
+
+  $::form->{type} = 'invoice';
+  $self->_transaction($self->is_vendor() ? 'ir.pl' : 'is.pl');
+}
+
+sub action_save_and_order {
+  my ($self) = @_;
+
+  if ( $self->is_vendor() ) {
+    $::auth->assert('purchase_order_edit');
+  } else {
+    $::auth->assert('sales_order_edit');
+  }
+
+  $::form->{type} = $self->is_vendor() ? 'purchase_order' : 'sales_order';
+  $self->_transaction('oe.pl');
+}
+
+sub action_save_and_rfq {
+  my ($self) = @_;
+
+  $::auth->assert('request_quotation_edit');
+
+  $::form->{type} = 'request_quotation';
+  $self->_transaction('oe.pl');
+}
+
+sub action_save_and_quotation {
+  my ($self) = @_;
+
+  $::auth->assert('sales_quotation_edit');
+
+  $::form->{type} = 'sales_quotation';
+  $self->_transaction('oe.pl');
+}
+
+sub action_delete {
+  my ($self) = @_;
+
+  my $db = $self->{cv}->db;
+
+  if( !$self->is_orphaned() ) {
+    $self->action_edit();
+  } else {
+
+    $db->do_transaction(sub {
+      $self->{cv}->delete(cascade => 1);
+
+      my $snumbers = $self->is_vendor() ? 'vendornumber_'. $self->{cv}->vendornumber : 'customernumber_'. $self->{cv}->customernumber;
+      SL::DB::History->new(
+        trans_id => $self->{cv}->id,
+        snumbers => $snumbers,
+        employee_id => SL::DB::Manager::Employee->current->id,
+        addition => 'DELETED',
+      )->save();
+    }) || die($db->error);
+
+    my $msg = $self->is_vendor() ? $::locale->text('Vendor deleted!') : $::locale->text('Customer deleted!');
+    $::form->redirect($msg);
+  }
+
+}
+
+
+sub action_delete_contact {
+  my ($self) = @_;
+
+  my $db = $self->{contact}->db;
+
+  if ( !$self->{contact}->cp_id ) {
+    SL::Helper::Flash::flash('error', $::locale->text('No contact selected to delete'));
+  } else {
+
+    $db->do_transaction(sub {
+      if ( $self->{contact}->used ) {
+        $self->{contact}->detach();
+        $self->{contact}->save();
+        SL::Helper::Flash::flash('info', $::locale->text('Contact is in use and was flagged invalid.'));
+      } else {
+        $self->{contact}->delete(cascade => 1);
+        SL::Helper::Flash::flash('info', $::locale->text('Contact deleted.'));
+      }
+    }) || die($db->error);
+
+    $self->{contact} = SL::DB::Contact->new();
+  }
+
+  $self->action_edit();
+}
+
+sub action_delete_shipto {
+  my ($self) = @_;
+
+  my $db = $self->{shipto}->db;
+
+  if ( !$self->{shipto}->shipto_id ) {
+    SL::Helper::Flash::flash('error', $::locale->text('No shipto selected to delete'));
+  } else {
+
+    $db->do_transaction(sub {
+      if ( $self->{shipto}->used ) {
+        $self->{shipto}->detach();
+        $self->{shipto}->save(cascade => 1);
+        SL::Helper::Flash::flash('info', $::locale->text('Shipto is in use and was flagged invalid.'));
+      } else {
+        $self->{shipto}->delete(cascade => 1);
+        SL::Helper::Flash::flash('info', $::locale->text('Shipto deleted.'));
+      }
+    }) || die($db->error);
+
+    $self->{shipto} = SL::DB::Shipto->new();
+  }
+
+  $self->action_edit();
+}
+
+
+sub action_search {
+  my ($self) = @_;
+
+  my $url = 'ct.pl?action=search&db='. ($self->is_vendor() ? 'vendor' : 'customer');
+
+  if ( $::form->{callback} ) {
+    $url .= '&callback='. $::from->escape($::form->{callback});
+  }
+
+  print $::form->redirect_header($url);
+}
+
+
+sub action_search_contact {
+  my ($self) = @_;
+
+  my $url = 'ct.pl?action=search_contact&db=customer';
+
+  if ( $::form->{callback} ) {
+    $url .= '&callback='. $::from->escape($::form->{callback});
+  }
+
+  print $::form->redirect_header($url);
+}
+
+
+sub action_get_delivery {
+  my ($self) = @_;
+
+  my $dbh = $::form->get_standard_dbh();
+
+  my ($arap, $db, $qty_sign);
+  if ( $self->is_vendor() ) {
+    $arap = 'ap';
+    $db = 'vendor';
+    $qty_sign = ' * -1 AS qty';
+  } else {
+    $arap = 'ar';
+    $db = 'customer';
+    $qty_sign = '';
+  }
+
+  my $where = ' WHERE 1=1 ';
+  my @values;
+
+  if ( !$self->is_vendor() && $::form->{shipto_id} && $::form->{shipto_id} ne 'all' ) {
+    $where .= "AND ${arap}.shipto_id = ?";
+    push(@values, $::form->{shipto_id});
+  }
+
+  if ( $::form->{delivery_from} ) {
+    $where .= "AND ${arap}.transdate >= ?";
+    push(@values, conv_date($::form->{delivery_from}));
+  }
+
+  if ( $::form->{delivery_to} ) {
+    $where .= "AND ${arap}.transdate <= ?";
+    push(@values, conv_date($::form->{delivery_to}));
+  }
+
+  my $query =
+    "SELECT
+       s.shiptoname,
+       i.qty ${qty_sign},
+       ${arap}.id,
+       ${arap}.transdate,
+       ${arap}.invnumber,
+       ${arap}.ordnumber,
+       i.description,
+       i.unit,
+       i.sellprice,
+       oe.id AS oe_id,
+       invoice
+     FROM ${arap}
+
+     LEFT JOIN shipto s
+      ON ". ($arap eq 'ar' ? '(ar.shipto_id = s.shipto_id) ' : '(ap.id = s.trans_id) ') ."
+
+     LEFT JOIN invoice i
+       ON ${arap}.id = i.trans_id
+
+     LEFT JOIN parts p
+       ON p.id = i.parts_id
+
+     LEFT JOIN oe
+       ON (oe.ordnumber = ${arap}.ordnumber AND NOT ${arap}.ordnumber = '')
+
+     ${where}
+     ORDER BY ${arap}.transdate DESC LIMIT 15";
+
+  $self->{delivery} = selectall_hashref_query($::form, $dbh, $query, @values);
+
+  $self->render('customer_vendor/get_delivery', { layout => 0 });
+}
+
+sub action_ajaj_get_shipto {
+  my ($self) = @_;
+
+  my $data = {
+    map(
+      {
+        my $name = 'shipto'. $_;
+        $name => $self->{shipto}->$name;
+      }
+      qw(_id name department_1 department_2 street zipcode city country contact phone fax email)
+    )
+  };
+
+  $self->render(\SL::JSON::to_json($data), { type => 'json', process => 0 });
+}
+
+sub action_ajaj_get_contact {
+  my ($self) = @_;
+
+  my $data;
+
+  $data->{contact} = {
+    map(
+      {
+        my $name = 'cp_'. $_;
+
+        if ( $_ eq 'birthday' && $self->{contact}->$name ) {
+          $name => $self->{contact}->$name->to_lxoffice;
+        } else {
+          $name => $self->{contact}->$name;
+        }
+      }
+      qw(
+        id gender abteilung title position givenname name email phone1 phone2 fax mobile1 mobile2
+        satphone satfax project street zipcode city privatphone privatemail birthday
+      )
+    )
+  };
+
+  $data->{contact_cvars} = {
+    map(
+      {
+        if ( $_->config->type eq 'number' ) {
+          $_->config->name => $::form->format_amount(\%::myconfig, $_->value, -2);
+        } else {
+          $_->config->name => $_->value;
+        }
+      }
+      grep(
+        { $_->is_valid; }
+        @{$self->{contact}->cvars_by_config}
+      )
+    )
+  };
+
+  $self->render(\SL::JSON::to_json($data), { type => 'json', process => 0 });
+}
+
+sub action_ajaj_customer_autocomplete {
+  my ($self, %params) = @_;
+
+  my $limit = $::form->{limit} || 20;
+  my $type  = $::form->{type}  || {};
+  my $query = { ilike => '%'. $::form->{term} .'%' };
+
+  my @filter;
+  push(
+    @filter,
+    $::form->{column} ? ($::form->{column} => $query) : (or => [ customernumber => $query, name => $query ])
+  );
+
+  my $customers = SL::DB::Manager::Customer->get_all(query => [ @filter ], limit => $limit);
+  my $value_col = $::form->{column} || 'name';
+
+  my $data = [
+    map(
+      {
+        {
+          value => $_->can($value_col)->($_),
+          label => $_->displayable_name,
+          id    => $_->id,
+          customernumber => $_->customernumber,
+          name  => $_->name,
+        }
+      }
+      @{$customers}
+    )
+  ];
+
+  $self->render(\SL::JSON::to_json($data), { layout => 0, type => 'json' });
+}
+
+sub is_vendor {
+  return $::form->{db} eq 'vendor';
+}
+
+sub is_customer {
+  return $::form->{db} eq 'customer';
+}
+
+sub is_orphaned {
+  my ($self) = @_;
+
+  if ( defined($self->{_is_orphaned}) ) {
+    return $self->{_is_orphaned};
+  }
+
+  my $arap      = $self->is_vendor ? 'ap' : 'ar';
+  my $num_args  = 2;
+
+  my $cv = $self->is_vendor ? 'vendor' : 'customer';
+
+  my $query =
+   'SELECT a.id
+    FROM '. $arap .' AS a
+    JOIN '. $cv .' ct ON (a.'. $cv .'_id = ct.id)
+    WHERE ct.id = ?
+
+    UNION
+
+    SELECT a.id
+    FROM oe a
+    JOIN '. $cv .' ct ON (a.'. $cv .'_id = ct.id)
+    WHERE ct.id = ?';
+
+
+  if ( $self->is_vendor ) {
+    $query .=
+     ' UNION
+      SELECT 1 FROM makemodel mm WHERE mm.make = ?';
+    $num_args++;
+  }
+
+  my ($dummy) = selectrow_query($::form, $::form->get_standard_dbh(), $query, (conv_i($self->{cv}->id)) x $num_args);
+
+  return $self->{_is_orphaned} = !$dummy;
+}
+
+sub _instantiate_args {
+  my ($self) = @_;
+
+  my $curr_employee = SL::DB::Manager::Employee->current;
+
+  if ( $::form->{cv}->{id} ) {
+    if ( $self->is_vendor() ) {
+      $self->{cv} = SL::DB::Vendor->new(id => $::form->{cv}->{id})->load();
+    } else {
+      $self->{cv} = SL::DB::Customer->new(id => $::form->{cv}->{id})->load();
+    }
+  } else {
+    if ( $self->is_vendor() ) {
+      $self->{cv} = SL::DB::Vendor->new();
+    } else {
+      $self->{cv} = SL::DB::Customer->new();
+    }
+  }
+  $self->{cv}->assign_attributes(%{$::form->{cv}});
+
+  foreach my $cvar (@{$self->{cv}->cvars_by_config()}) {
+    my $value = $::form->{cv_cvars}->{$cvar->config->name};
+
+    if ( $cvar->config->type eq 'number' ) {
+      $value = $::form->parse_amount(\%::myconfig, $value);
+    }
+
+    $cvar->value($value);
+  }
+
+  if ( $::form->{note}->{id} ) {
+    $self->{note} = SL::DB::Note->new(id => $::form->{note}->{id})->load();
+  } else {
+    $self->{note} = SL::DB::Note->new();
+  }
+  $self->{note}->assign_attributes(%{$::form->{note}});
+  $self->{note}->created_by($curr_employee->id);
+  $self->{note}->trans_module('ct');
+
+  $self->{note_followup} = SL::DB::FollowUp->new();
+  $self->{note_followup}->assign_attributes(%{$::form->{note_followup}});
+  $self->{note_followup}->note($self->{note});
+  $self->{note_followup}->created_by($curr_employee->id);
+
+  if ( $::form->{shipto}->{shipto_id} ) {
+    $self->{shipto} = SL::DB::Shipto->new(shipto_id => $::form->{shipto}->{shipto_id})->load();
+  } else {
+    $self->{shipto} = SL::DB::Shipto->new();
+  }
+  $self->{shipto}->assign_attributes(%{$::form->{shipto}});
+  $self->{shipto}->module('CT');
+
+  if ( $::form->{contact}->{cp_id} ) {
+    $self->{contact} = SL::DB::Contact->new(cp_id => $::form->{contact}->{cp_id})->load();
+  } else {
+    $self->{contact} = SL::DB::Contact->new();
+  }
+  $self->{contact}->assign_attributes(%{$::form->{contact}});
+
+  foreach my $cvar (@{$self->{contact}->cvars_by_config()}) {
+    my $value = $::form->{contact_cvars}->{$cvar->config->name};
+
+    if ( $cvar->config->type eq 'number' ) {
+      $value = $::form->parse_amount(\%::myconfig, $value);
+    }
+
+    $cvar->value($value);
+  }
+}
+
+sub _load_customer_vendor {
+  my ($self) = @_;
+
+  if ( $self->is_vendor() ) {
+    $self->{cv} = SL::DB::Vendor->new(id => $::form->{id})->load();
+  } else {
+    $self->{cv} = SL::DB::Customer->new(id => $::form->{id})->load();
+  }
+
+  $self->{note} = SL::DB::Note->new();
+  $self->{note_followup} = SL::DB::FollowUp->new();
+
+  if ( $::form->{shipto_id} ) {
+    $self->{shipto} = SL::DB::Shipto->new(shipto_id => $::form->{shipto_id})->load();
+
+    if ( $self->{shipto}->trans_id != $self->{cv}->id ) {
+      die($::locale->text('Error'));
+    }
+  } else {
+    $self->{shipto} = SL::DB::Shipto->new();
+  }
+
+  if ( $::form->{contact_id} ) {
+    $self->{contact} = SL::DB::Contact->new(cp_id => $::form->{contact_id})->load();
+
+    if ( $self->{contact}->cp_cv_id != $self->{cv}->id ) {
+      die($::locale->text('Error'));
+    }
+  } else {
+    $self->{contact} = SL::DB::Contact->new();
+  }
+}
+
+sub _create_customer_vendor {
+  my ($self) = @_;
+
+  if ( $self->is_vendor() ) {
+    $self->{cv} = SL::DB::Vendor->new();
+  } else {
+    $self->{cv} = SL::DB::Customer->new();
+  }
+
+  $self->{note} = SL::DB::Note->new();
+
+  $self->{note_followup} = SL::DB::FollowUp->new();
+
+  $self->{shipto} = SL::DB::Shipto->new();
+
+  $self->{contact} = SL::DB::Contact->new();
+}
+
+sub _pre_render {
+  my ($self) = @_;
+
+  $self->{template_args}->{conf_vertreter} = $::instance_conf->get_vertreter();
+
+  my $dbh = $::form->get_standard_dbh();
+
+  my $query;
+
+  $self->{all_business} = SL::DB::Manager::Business->get_all();
+
+  $self->{all_employees} = SL::DB::Manager::Employee->get_all(query => [ deleted => 0 ]);
+
+  $query =
+    'SELECT DISTINCT(greeting)
+     FROM customer
+     WHERE greeting IS NOT NULL AND greeting != \'\'
+     UNION
+       SELECT DISTINCT(greeting)
+       FROM vendor
+       WHERE greeting IS NOT NULL AND greeting != \'\'
+     ORDER BY greeting';
+  $self->{all_greetings} = [
+    map(
+      { $_->{greeting}; }
+      selectall_hashref_query($::form, $dbh, $query)
+    )
+  ];
+
+  $query =
+    'SELECT DISTINCT(cp_title) AS title
+     FROM contacts
+     WHERE cp_title IS NOT NULL AND cp_title != \'\'
+     ORDER BY cp_title';
+  $self->{all_titles} = [
+    map(
+      { $_->{title}; }
+      selectall_hashref_query($::form, $dbh, $query)
+    )
+  ];
+
+  $self->{all_currencies} = SL::DB::Manager::Currency->get_all();
+
+  $self->{all_languages} = SL::DB::Manager::Language->get_all();
+
+  $self->{all_taxzones} = SL::DB::Manager::TaxZone->get_all();
+
+  if ( $::instance_conf->get_vertreter() ) {
+    $query =
+      'SELECT id
+       FROM business
+       WHERE salesman';
+    my $business_ids = [
+      map(
+        { $_->{id}; }
+        selectall_hashref_query($::form, $dbh, $query)
+      )
+    ];
+
+    if ( $business_ids->[0] ) {
+      $self->{all_salesman_customers} = SL::DB::Manager::Customer->get_all(query => [business_id => $business_ids]);
+    } else {
+      $self->{all_salesman_customers} = [];
+    }
+  } else {
+    $self->{all_salesmen} = SL::DB::Manager::Employee->get_all(query => [ or => [ id => $self->{cv}->salesman_id,  deleted => 0 ] ]);
+  }
+
+  $self->{all_payment_terms} = SL::DB::Manager::PaymentTerm->get_all();
+
+  $self->{all_pricegroups} = SL::DB::Manager::Pricegroup->get_all();
+
+  $query =
+    'SELECT DISTINCT(cp_abteilung) AS department
+     FROM contacts
+     WHERE cp_abteilung IS NOT NULL AND cp_abteilung != \'\'
+     ORDER BY cp_abteilung';
+  $self->{all_departments} = [
+    map(
+      { $_->{department}; }
+      selectall_hashref_query($::form, $dbh, $query)
+    )
+  ];
+
+  $self->{contacts} = $self->{cv}->contacts;
+  $self->{contacts} ||= [];
+
+  $self->{shiptos} = $self->{cv}->shipto;
+  $self->{shiptos} ||= [];
+
+  $self->{template_args} ||= {};
+
+  $::request->{layout}->add_javascripts('autocomplete_customer.js');
+  $::request->{layout}->add_javascripts('kivi.CustomerVendor.js');
+}
+
+1;
index 00adfc9..b8ee1c4 100644 (file)
@@ -228,7 +228,7 @@ sub link_to {
   }
   if ($object->isa('SL::DB::Customer')) {
     my $id     = $object->id;
-    return "ct.pl?action=$action&id=$id&db=customer";
+    return "controller.pl?action=CustomerVendor/$action&id=$id&db=customer";
   }
 }
 
index ba208c4..f894e06 100644 (file)
@@ -28,6 +28,7 @@ __PACKAGE__->run_before('load_unit_from_form',   only => [ qw(stock_in part_chan
 __PACKAGE__->run_before('load_wh_from_form',     only => [ qw(stock_in warehouse_changed stock) ]);
 __PACKAGE__->run_before('load_bin_from_form',    only => [ qw(stock_in stock) ]);
 __PACKAGE__->run_before('set_target_from_part',  only => [ qw(part_changed) ]);
+__PACKAGE__->run_before('mini_stock',            only => [ qw(stock_in mini_stock) ]);
 __PACKAGE__->run_before('sanitize_target',       only => [ qw(stock_in warehouse_changed part_changed) ]);
 __PACKAGE__->run_before('set_layout');
 
@@ -70,6 +71,7 @@ sub action_stock {
     part_id      => $self->part->id,
     bin_id       => $self->bin->id,
     warehouse_id => $self->warehouse->id,
+    unit_id      => $self->unit->id,
   );
 }
 
@@ -104,22 +106,11 @@ sub action_warehouse_changed {
 sub action_mini_stock {
   my ($self) = @_;
 
-  my $stock        = $self->part->get_simple_stock;
-  my $stock_by_bin = { map { $_->{bin_id} => $_ } @$stock };
-  my $stock_empty  = ! grep { $_->{sum} * 1 } @$stock;
-
   $self->js
-    ->html('#stock', $self->render('inventory/_stock', { output => 0 }, stock => $stock_by_bin, stock_empty => $stock_empty ))
+    ->html('#stock', $self->render('inventory/_stock', { output => 0 }))
     ->render($self);
 }
 
-sub action_last_journal {
-  my ($self) = @_;
-
-#  my $jounal = $self->journal;
-
-}
-
 #================================================================
 
 sub _check_auth {
@@ -215,7 +206,8 @@ sub mini_journal {
   my $query = 'SELECT trans_id, max(itime) FROM inventory GROUP BY trans_id ORDER BY max(itime) DESC LIMIT 10';
   my @ids = selectall_array_query($::form, $::form->get_standard_dbh, $query);
 
-  my $objs = SL::DB::Manager::Inventory->get_all(query => [ trans_id => \@ids ]);
+  my $objs;
+  $objs = SL::DB::Manager::Inventory->get_all(query => [ trans_id => \@ids ]) if @ids;
 
   # at most 2 of them belong to a transaction and the qty determins in or out.
   # sort them for display
@@ -230,6 +222,14 @@ sub mini_journal {
   return \@sorted;
 }
 
+sub mini_stock {
+  my ($self) = @_;
+
+  my $stock             = $self->part->get_simple_stock;
+  $self->{stock_by_bin} = { map { $_->{bin_id} => $_ } @$stock };
+  $self->{stock_empty}  = ! grep { $_->{sum} * 1 } @$stock;
+}
+
 sub show_no_warehouse_error {
   my ($self) = @_;
 
index ba10984..e84a315 100644 (file)
@@ -129,6 +129,19 @@ sub _redirect_to_main_script_if_already_logged_in {
   my %user = $::auth->read_user(login => $login);
   return if ($user{login} || '') ne $login;
 
+  # Check if there's a client set in the session -- and whether or not
+  # the user still has access to the client.
+  my $client_id = $::auth->get_session_value('client_id');
+  return if !$client_id;
+
+  if (!$::auth->set_client($client_id)) {
+    $::auth->punish_wrong_login;
+    $::auth->destroy_session;
+    $::auth->create_or_refresh_session;
+    $self->show_login_form(error => t8('Incorrect username or password or no access to selected client!'));
+    return 1;
+  }
+
   # Check if the session is logged in correctly.
   return if SL::Auth::OK() != $::auth->authenticate($login, undef);
 
index f31f53e..8e0c52d 100644 (file)
@@ -141,7 +141,7 @@ sub link_to {
   }
   if ($object->isa('SL::DB::Customer')) {
     my $id     = $object->id;
-    return "ct.pl?action=$action&id=$id&db=customer";
+    return "controller.pl?action=CustomerVendor/$action&id=$id&db=customer";
   }
 }
 
index 09718de..60955e4 100644 (file)
@@ -4,7 +4,6 @@
 package SL::DB::CustomVariable;
 
 use strict;
-
 use SL::DB::MetaSetup::CustomVariable;
 
 __PACKAGE__->meta->initialize;
@@ -19,7 +18,27 @@ sub value {
   goto &bool_value      if $type eq 'boolean';
   goto &timestamp_value if $type eq 'timestamp';
   goto &number_value    if $type eq 'number';
+  if ( $type eq 'customer' ) {
+    if ( defined($_[1]) && $_[1] ) {
+      goto &number_value;
+    }
+    else {
+      require SL::DB::Customer;
+
+      my $id = int($self->number_value);
+      return $id ? SL::DB::Customer->new(id => $id)->load() : 0;
+    }
+  }
   goto &text_value; # text and select
 }
 
+sub is_valid {
+  my ($self) = @_;
+
+  require SL::DB::CustomVariableValidity;
+
+  my $query = [config_id => $self->config_id, trans_id => $self->trans_id];
+  return SL::DB::Manager::CustomVariableValidity->get_all_count(query => $query) == 0;
+}
+
 1;
index fd247d8..203f83a 100644 (file)
@@ -25,4 +25,66 @@ sub validate {
   return @errors;
 }
 
+use constant OPTION_DEFAULTS =>
+  {
+    MAXLENGTH => 75,
+    WIDTH => 30,
+    HEIGHT => 5,
+  };
+
+sub processed_options {
+  my ($self) = @_;
+
+  if( exists($self->{processed_options_cache}) ) {
+    return $self->{processed_options_cache};
+  }
+
+  my $ops = $self->options;
+  my $ret;
+
+  if ( $self->type eq 'select' ) {
+    my @op_array = split('##', $ops);
+    $ret = \@op_array;
+  }
+  else {
+    $ret = {%{$self->OPTION_DEFAULTS}};
+    while ( $ops =~ /\s*([^=\s]+)\s*=\s*([^\s]*)(?:\s*|$)/g ) {
+      $ret->{$1} = $2;
+    }
+  }
+
+  $self->{processed_options_cache} = $ret;
+
+  return $ret;
+}
+
+sub processed_flags {
+  my ($self) = @_;
+
+  if( exists($self->{processed_flags_cache}) ) {
+    return $self->{processed_flags_cache};
+  }
+
+  my $flags = $self->flags;
+  my $ret;
+
+  foreach my $flag (split m/:/, $flags) {
+    if ( $flag =~ m/(.*?)=(.*)/ ) {
+      $ret->{$1} = $2;
+    } else {
+      $ret->{$flag} = 1;
+    }
+  }
+
+  $self->{processed_flags_cache} = $ret;
+
+  return $ret;
+}
+
+sub has_flag {
+  my ($self, $flag) = @_;
+
+  return $self->processed_flags()->{$flag};
+}
+
 1;
index df90aa7..3c43624 100644 (file)
@@ -78,7 +78,19 @@ sub make_cvar_by_configs {
     my $cvars       = $self->custom_variables;
     my %cvars_by_config = map { $_->config_id => $_ } @$cvars;
 
-    my @return  = map { $cvars_by_config{$_->id} || _new_cvar($self, %params, config => $_) } @$configs;
+    my @return = map(
+      {
+        if ( $cvars_by_config{$_->id} ) {
+          $cvars_by_config{$_->id};
+        }
+        else {
+          my $cvar = _new_cvar($self, %params, config => $_);
+          $self->add_custom_variables($cvar);
+          $cvar;
+        }
+      }
+      @$configs
+    );
 
     return \@return;
   }
index ccfb97e..c5b45de 100644 (file)
@@ -17,4 +17,8 @@ sub _sort_spec {
            columns => { SIMPLE => 'ALL' } );
 }
 
+sub get_default {
+  return $_[0]->get_first(where => [ is_default => 1 ]);
+}
+
 1;
index 82c5776..441a273 100644 (file)
@@ -12,4 +12,12 @@ __PACKAGE__->meta->initialize;
 # Creates get_all, get_all_count, get_all_iterator, delete_all and update_all.
 __PACKAGE__->meta->make_manager_class;
 
+__PACKAGE__->meta->add_relationships(
+  followup => {
+    type         => 'one to one',
+    class        => 'SL::DB::FollowUp',
+    column_map   => { id => 'id' },
+  },
+);
+
 1;
index a005c18..8131a2c 100644 (file)
--- a/SL/FU.pm
+++ b/SL/FU.pm
@@ -314,13 +314,13 @@ sub link_details {
 
   if ($params{trans_type} eq 'customer') {
     $link = {
-      'url'   => 'ct.pl?action=edit&db=customer&id=' . $form->quote($params{trans_id}) . '&edit_note_id=' . $form->quote($params{note_id}),
+      'url'   => 'controller.pl?action=CustomerVendor/edit&db=customer&id=' . $form->quote($params{trans_id}) . '&edit_note_id=' . $form->quote($params{note_id}),
       'title' => $locale->text('Customer') . " '$params{trans_info}'",
     };
 
   } elsif ($params{trans_type} eq 'vendor') {
     $link = {
-      'url'   => 'ct.pl?action=edit&type=sales_quotation&id=' . $params{trans_id} . '&edit_note_id=' . $form->quote($params{note_id}),
+      'url'   => 'controller.pl?action=CustomerVendor/edit&type=sales_quotation&id=' . $params{trans_id} . '&edit_note_id=' . $form->quote($params{note_id}),
       'title' => $locale->text('Vendor') . " '$params{trans_info}'",
     };
 
index b18bc67..39bd9a5 100644 (file)
@@ -465,7 +465,7 @@ sub header {
   # this should gradually move to the layouts that need it
   $layout->use_stylesheet("$_.css") for qw(
     main menu list_accounts jquery.autocomplete
-    jquery.multiselect2side frame_header/header
+    jquery.multiselect2side
     ui-lightness/jquery-ui
     jquery-ui.custom jqModal
   );
index 13c4d1c..6995689 100644 (file)
@@ -4,10 +4,11 @@ use strict;
 
 use Carp;
 use SL::DBUtils ();
+use SL::System::Process;
 
 use parent qw(Rose::Object);
 use Rose::Object::MakeMethods::Generic (
-  'scalar --get_set_init' => [ qw(data currencies default_currency _table_currencies_exists) ],
+  'scalar --get_set_init' => [ qw(data currencies default_currency _table_currencies_exists crm_installed) ],
 );
 
 sub init_data {
@@ -34,6 +35,10 @@ sub init_default_currency {
   return (SL::DBUtils::selectfirst_array_query($::form, $::form->get_standard_dbh, qq|SELECT name FROM currencies WHERE id = ?|, $self->data->{currency_id}))[0];
 }
 
+sub crm_installed {
+  return -f (SL::System::Process->exe_dir . '/crm/Changelog');
+}
+
 sub reload {
   my ($self) = @_;
 
@@ -93,9 +98,9 @@ C<$::instance_conf>.
 
 Creates a new instance. Does not read the configuration.
 
-=item C<init>
+=item C<crm_installed>
 
-Reads the configuration from the database. Returns C<$self>.
+Returns trueish if the CRM component is installed.
 
 =item C<get_currencies>
 
index 00e3125..8b75c89 100644 (file)
@@ -1,18 +1,32 @@
 package SL::Layout::Admin;
 
 use strict;
-use parent qw(SL::Layout::Base);
+use parent qw(SL::Layout::V3);
 
-sub init_sub_layouts {
-  [ SL::Layout::None->new ]
+use SL::Menu;
+
+use Rose::Object::MakeMethods::Generic (
+  scalar => [ qw(no_menu) ],
+);
+
+
+sub init_menu {
+  Menu->new('menus/admin.ini');
 }
 
 sub start_content {
   "<div id='admin' class='admin'>\n";
 }
 
-sub end_content {
-  "</div>\n";
+sub render {
+  my ($self) = @_;
+
+  $self->presenter->render(
+    'menu/menuv3',
+    force_ul_width    => 1,
+    skip_frame_header => 1,
+    menu              => $self->no_menu ? '' : $self->print_menu,
+  );
 }
 
 1;
index 2212f71..7932aff 100644 (file)
@@ -29,7 +29,9 @@ sub new {
 }
 
 sub init_menu {
-  Menu->new('menu.ini');
+  my @menu_files = qw(menus/erp.ini);
+  unshift @menu_files, 'menus/crm.ini' if $::instance_conf->crm_installed;
+  Menu->new(@menu_files);
 }
 
 sub init_auto_reload_resources_param {
@@ -327,4 +329,3 @@ None yet, if you don't count the horrible stylesheet/javascript interface.
 Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>
 
 =cut
-
index b08cf6d..93704be 100644 (file)
@@ -34,6 +34,7 @@ sub stylesheets {
   $_[0]->add_stylesheets(qw(
     dhtmlsuite/menu-item.css
     dhtmlsuite/menu-bar.css
+    frame_header/header.css
     menu.css
   ));
   $_[0]->SUPER::stylesheets;
index ed7733c..f37eea4 100644 (file)
@@ -146,7 +146,7 @@ sub use_javascript {
 }
 
 sub pre_content {
-  &render;
+  $_[0]->render;
 }
 
 sub start_content {
index 0fb1b1a..06ea6ee 100644 (file)
@@ -42,14 +42,19 @@ use strict;
 sub new {
   $main::lxdebug->enter_sub();
 
-  my ($type, $menufile) = @_;
+  my ($type, @menufiles) = @_;
+  my $self               = bless {}, $type;
 
-  my $self    = {};
-  my $inifile = Inifile->new($menufile);
+  my @order;
 
-  map { $self->{$_} = $inifile->{$_} } keys %{ $inifile };
+  foreach my $menufile (grep { -f } @menufiles) {
+    my $inifile = Inifile->new($menufile);
 
-  bless $self, $type;
+    push @order, @{ delete($inifile->{ORDER}) || [] };
+    $self->{$_} = $inifile->{$_} for keys %{ $inifile };
+  }
+
+  $self->{ORDER} = \@order;
 
   $self->set_access();
 
index 077c376..6d24409 100644 (file)
@@ -27,7 +27,7 @@ sub _customer_vendor {
   croak "Unknown display type '$params{display}'" unless $params{display} =~ m/^(?:inline|table-cell)$/;
 
   my $text = join '', (
-    $params{no_link} ? '' : '<a href="ct.pl?action=edit&amp;db=' . $type . '&amp;id=' . $self->escape($cv->id) . '">',
+    $params{no_link} ? '' : '<a href="controller.pl?action=CustomerVendor/edit&amp;db=' . $type . '&amp;id=' . $self->escape($cv->id) . '">',
     $self->escape($cv->name),
     $params{no_link} ? '' : '</a>',
   );
index 241ea0e..16989e9 100644 (file)
@@ -17,13 +17,23 @@ sub new {
 # public interface
 #
 
+# see ecmascript spec section 7.8.4
+my @escape_chars = ('\\', '\'', '"');
+my %control_chars = (
+  "\n"   => 'n',
+  "\t"   => 't',
+  "\r"   => 'r',
+  "\f"   => 'f',
+  "\x08" => 'b',
+  "\x0B" => 'v', # noone uses vertical tab anyway...
+);
+my $re = join '', map { qr/($_)/s } join '|', keys(%control_chars), map { "\Q$_\E" } @escape_chars;
+
 sub escape {
   my $self = shift;
   my $text = shift;
 
-  $text =~ s|\\|\\\\|g;
-  $text =~ s|\"|\\\"|g;
-  $text =~ s|\n|\\n|g;
+  $text =~ s/$re/'\\' . ($control_chars{$1} || $1)/egs;
 
   return $text;
 }
index 4291871..59e7dbb 100644 (file)
@@ -270,7 +270,7 @@ sub list_names {
       $previous_id = $ref->{id};
       map { $row->{$_}->{data} = $ref->{$_} } @columns;
 
-      $row->{name}->{link}  = build_std_url('action=edit', 'id=' . E($ref->{id}), 'callback', @hidden_nondefault);
+      $row->{name}->{link}  = build_std_url('script=controller.pl', 'action=CustomerVendor/edit', 'id=' . E($ref->{id}), 'callback', @hidden_nondefault);
       $row->{email}->{link} = 'mailto:' . E($ref->{email});
     }
 
index b8cda2b..15f58fc 100644 (file)
@@ -829,6 +829,22 @@ sub generate_report {
   # filter stuff
   map { $filter{$_} = $form->{$_} if ($form->{$_}) } qw(warehouse_id bin_id partnumber description chargenumber bestbefore date include_invalid_warehouses);
 
+  # show filter stuff also in report
+  my @options;
+  # dispatch all options
+  my $dispatch_options = {
+   partnumber     => sub { push @options, $locale->text('Partnumber') . " : $form->{partnumber}"},
+   description    => sub { push @options, $locale->text('Description') . " : $form->{description}"},
+   chargenumber   => sub { push @options, $locale->text('Charge Number') . " : $form->{chargenumber}"},
+   bestbefore     => sub { push @options, $locale->text('Best Before') . " : $form->{bestbefore}"},
+   date           => sub { push @options, $locale->text('Date') . " : $form->{date}"},
+   include_invalid_warehouses    => sub { push @options, $locale->text('Include invalid warehouses ')},
+  };
+  foreach (keys %filter) {
+    defined $dispatch_options->{$_}  && $dispatch_options->{$_}->();
+  }
+  # / end show filter stuff also in report
+
   $filter{qty_op} = WH->convert_qty_op($form->{qty_op});
   if ($filter{qty_op}) {
     $form->isblank("qty",      $locale->text('Quantity missing.'));
@@ -872,7 +888,8 @@ sub generate_report {
 
   $report->set_sort_indicator($sort_col, $form->{order});
 
-  $report->set_options('output_format'        => 'HTML',
+  $report->set_options('top_info_text'        => join("\n", @options),
+                       'output_format'        => 'HTML',
                        'title'                => $form->{title},
                        'attachment_basename'  => strftime($locale->text('warehouse_report_list') . '_%Y%m%d', localtime time));
   $report->set_options_from_form();
index c8ed512..5de8b42 100644 (file)
@@ -61,6 +61,8 @@ Kleinere neue Features und Detailverbesserungen:
 - Offene Forderungen / Verbindlichkeiten
   Stichtagsbezogene Auswahl korrekt mit Fälligkeit verrechnet
 
+- Lagerbestand anzeigen, zeigt auch die Filteroptionen an
+
 - #1897 implementiert. Zukunfts-Buchungen verhindern, durch einen konfigurierbaren
   maximalen Zeitraum in dem in die Zukunft gebucht werden darf (default 360 Tage)
 
diff --git a/image/icons/16x16/CRM--Add--Customer.png b/image/icons/16x16/CRM--Add--Customer.png
new file mode 100644 (file)
index 0000000..09d4ec7
Binary files /dev/null and b/image/icons/16x16/CRM--Add--Customer.png differ
diff --git a/image/icons/16x16/CRM--Add--Person.png b/image/icons/16x16/CRM--Add--Person.png
new file mode 100644 (file)
index 0000000..4605a14
Binary files /dev/null and b/image/icons/16x16/CRM--Add--Person.png differ
diff --git a/image/icons/16x16/CRM--Add--Vendor.png b/image/icons/16x16/CRM--Add--Vendor.png
new file mode 100644 (file)
index 0000000..8aac504
Binary files /dev/null and b/image/icons/16x16/CRM--Add--Vendor.png differ
diff --git a/image/icons/16x16/CRM--Admin--Benutzer.png b/image/icons/16x16/CRM--Admin--Benutzer.png
deleted file mode 100644 (file)
index f44429a..0000000
Binary files a/image/icons/16x16/CRM--Admin--Benutzer.png and /dev/null differ
diff --git a/image/icons/16x16/CRM--Admin--Document Template.png b/image/icons/16x16/CRM--Admin--Document Template.png
new file mode 100644 (file)
index 0000000..2d2ddc0
Binary files /dev/null and b/image/icons/16x16/CRM--Admin--Document Template.png differ
diff --git a/image/icons/16x16/CRM--Admin--Dokumentvorlage.png b/image/icons/16x16/CRM--Admin--Dokumentvorlage.png
deleted file mode 100644 (file)
index 2d2ddc0..0000000
Binary files a/image/icons/16x16/CRM--Admin--Dokumentvorlage.png and /dev/null differ
diff --git a/image/icons/16x16/CRM--Admin--Etiketten.png b/image/icons/16x16/CRM--Admin--Etiketten.png
deleted file mode 100644 (file)
index 9f1e784..0000000
Binary files a/image/icons/16x16/CRM--Admin--Etiketten.png and /dev/null differ
diff --git a/image/icons/16x16/CRM--Admin--Gruppen.png b/image/icons/16x16/CRM--Admin--Gruppen.png
deleted file mode 100644 (file)
index e7e9735..0000000
Binary files a/image/icons/16x16/CRM--Admin--Gruppen.png and /dev/null differ
diff --git a/image/icons/16x16/CRM--Admin--Label.png b/image/icons/16x16/CRM--Admin--Label.png
new file mode 100644 (file)
index 0000000..9f1e784
Binary files /dev/null and b/image/icons/16x16/CRM--Admin--Label.png differ
diff --git a/image/icons/16x16/CRM--Admin--Message.png b/image/icons/16x16/CRM--Admin--Message.png
new file mode 100644 (file)
index 0000000..c26531f
Binary files /dev/null and b/image/icons/16x16/CRM--Admin--Message.png differ
diff --git a/image/icons/16x16/CRM--Admin--Mitteilungen.png b/image/icons/16x16/CRM--Admin--Mitteilungen.png
deleted file mode 100644 (file)
index c26531f..0000000
Binary files a/image/icons/16x16/CRM--Admin--Mitteilungen.png and /dev/null differ
diff --git a/image/icons/16x16/CRM--Admin--User Groups.png b/image/icons/16x16/CRM--Admin--User Groups.png
new file mode 100644 (file)
index 0000000..e7e9735
Binary files /dev/null and b/image/icons/16x16/CRM--Admin--User Groups.png differ
diff --git a/image/icons/16x16/CRM--Admin--User.png b/image/icons/16x16/CRM--Admin--User.png
new file mode 100644 (file)
index 0000000..f44429a
Binary files /dev/null and b/image/icons/16x16/CRM--Admin--User.png differ
diff --git a/image/icons/16x16/CRM--Appointments.png b/image/icons/16x16/CRM--Appointments.png
new file mode 100644 (file)
index 0000000..8e05dd2
Binary files /dev/null and b/image/icons/16x16/CRM--Appointments.png differ
diff --git a/image/icons/16x16/CRM--Auftragschance.png b/image/icons/16x16/CRM--Auftragschance.png
deleted file mode 100644 (file)
index 4bd6383..0000000
Binary files a/image/icons/16x16/CRM--Auftragschance.png and /dev/null differ
diff --git a/image/icons/16x16/CRM--E-mail.png b/image/icons/16x16/CRM--E-mail.png
new file mode 100644 (file)
index 0000000..8bbabc0
Binary files /dev/null and b/image/icons/16x16/CRM--E-mail.png differ
diff --git a/image/icons/16x16/CRM--Follow-Up.png b/image/icons/16x16/CRM--Follow-Up.png
new file mode 100644 (file)
index 0000000..391b25d
Binary files /dev/null and b/image/icons/16x16/CRM--Follow-Up.png differ
diff --git a/image/icons/16x16/CRM--Help.png b/image/icons/16x16/CRM--Help.png
new file mode 100644 (file)
index 0000000..3fec0b3
Binary files /dev/null and b/image/icons/16x16/CRM--Help.png differ
diff --git a/image/icons/16x16/CRM--Hilfe.png b/image/icons/16x16/CRM--Hilfe.png
deleted file mode 100644 (file)
index 3fec0b3..0000000
Binary files a/image/icons/16x16/CRM--Hilfe.png and /dev/null differ
diff --git a/image/icons/16x16/CRM--Knowledge.png b/image/icons/16x16/CRM--Knowledge.png
new file mode 100644 (file)
index 0000000..b6a5edc
Binary files /dev/null and b/image/icons/16x16/CRM--Knowledge.png differ
diff --git a/image/icons/16x16/CRM--Kunden.png b/image/icons/16x16/CRM--Kunden.png
deleted file mode 100644 (file)
index 09d4ec7..0000000
Binary files a/image/icons/16x16/CRM--Kunden.png and /dev/null differ
diff --git a/image/icons/16x16/CRM--Lieferant.png b/image/icons/16x16/CRM--Lieferant.png
deleted file mode 100644 (file)
index 8aac504..0000000
Binary files a/image/icons/16x16/CRM--Lieferant.png and /dev/null differ
diff --git a/image/icons/16x16/CRM--Memo.png b/image/icons/16x16/CRM--Memo.png
new file mode 100644 (file)
index 0000000..70c046f
Binary files /dev/null and b/image/icons/16x16/CRM--Memo.png differ
diff --git a/image/icons/16x16/CRM--Notizen.png b/image/icons/16x16/CRM--Notizen.png
deleted file mode 100644 (file)
index 70c046f..0000000
Binary files a/image/icons/16x16/CRM--Notizen.png and /dev/null differ
diff --git a/image/icons/16x16/CRM--Opportunity.png b/image/icons/16x16/CRM--Opportunity.png
new file mode 100644 (file)
index 0000000..4bd6383
Binary files /dev/null and b/image/icons/16x16/CRM--Opportunity.png differ
diff --git a/image/icons/16x16/CRM--Personen.png b/image/icons/16x16/CRM--Personen.png
deleted file mode 100644 (file)
index 4605a14..0000000
Binary files a/image/icons/16x16/CRM--Personen.png and /dev/null differ
diff --git a/image/icons/16x16/CRM--Schnellsuche.png b/image/icons/16x16/CRM--Schnellsuche.png
deleted file mode 100644 (file)
index cf45918..0000000
Binary files a/image/icons/16x16/CRM--Schnellsuche.png and /dev/null differ
diff --git a/image/icons/16x16/CRM--Search.png b/image/icons/16x16/CRM--Search.png
new file mode 100644 (file)
index 0000000..cf45918
Binary files /dev/null and b/image/icons/16x16/CRM--Search.png differ
diff --git a/image/icons/16x16/CRM--Termine.png b/image/icons/16x16/CRM--Termine.png
deleted file mode 100644 (file)
index 8e05dd2..0000000
Binary files a/image/icons/16x16/CRM--Termine.png and /dev/null differ
diff --git a/image/icons/16x16/CRM--Wiedervorlage.png b/image/icons/16x16/CRM--Wiedervorlage.png
deleted file mode 100644 (file)
index 391b25d..0000000
Binary files a/image/icons/16x16/CRM--Wiedervorlage.png and /dev/null differ
diff --git a/image/icons/16x16/CRM--Wissens-DB.png b/image/icons/16x16/CRM--Wissens-DB.png
deleted file mode 100644 (file)
index b6a5edc..0000000
Binary files a/image/icons/16x16/CRM--Wissens-DB.png and /dev/null differ
diff --git a/image/icons/16x16/CRM--eMail.png b/image/icons/16x16/CRM--eMail.png
deleted file mode 100644 (file)
index 8bbabc0..0000000
Binary files a/image/icons/16x16/CRM--eMail.png and /dev/null differ
diff --git a/image/icons/24x24/CRM--Add--Customer.png b/image/icons/24x24/CRM--Add--Customer.png
new file mode 100644 (file)
index 0000000..644a6f5
Binary files /dev/null and b/image/icons/24x24/CRM--Add--Customer.png differ
diff --git a/image/icons/24x24/CRM--Add--Person.png b/image/icons/24x24/CRM--Add--Person.png
new file mode 100644 (file)
index 0000000..b0a9b19
Binary files /dev/null and b/image/icons/24x24/CRM--Add--Person.png differ
diff --git a/image/icons/24x24/CRM--Add--Vendor.png b/image/icons/24x24/CRM--Add--Vendor.png
new file mode 100644 (file)
index 0000000..40b1ce0
Binary files /dev/null and b/image/icons/24x24/CRM--Add--Vendor.png differ
diff --git a/image/icons/24x24/CRM--Admin--Benutzer.png b/image/icons/24x24/CRM--Admin--Benutzer.png
deleted file mode 100644 (file)
index bfd6bc4..0000000
Binary files a/image/icons/24x24/CRM--Admin--Benutzer.png and /dev/null differ
diff --git a/image/icons/24x24/CRM--Admin--Document Template.png b/image/icons/24x24/CRM--Admin--Document Template.png
new file mode 100644 (file)
index 0000000..a5ee5ab
Binary files /dev/null and b/image/icons/24x24/CRM--Admin--Document Template.png differ
diff --git a/image/icons/24x24/CRM--Admin--Dokumentvorlage.png b/image/icons/24x24/CRM--Admin--Dokumentvorlage.png
deleted file mode 100644 (file)
index a5ee5ab..0000000
Binary files a/image/icons/24x24/CRM--Admin--Dokumentvorlage.png and /dev/null differ
diff --git a/image/icons/24x24/CRM--Admin--Etiketten.png b/image/icons/24x24/CRM--Admin--Etiketten.png
deleted file mode 100644 (file)
index 5164bba..0000000
Binary files a/image/icons/24x24/CRM--Admin--Etiketten.png and /dev/null differ
diff --git a/image/icons/24x24/CRM--Admin--Gruppen.png b/image/icons/24x24/CRM--Admin--Gruppen.png
deleted file mode 100644 (file)
index b7875dc..0000000
Binary files a/image/icons/24x24/CRM--Admin--Gruppen.png and /dev/null differ
diff --git a/image/icons/24x24/CRM--Admin--Label.png b/image/icons/24x24/CRM--Admin--Label.png
new file mode 100644 (file)
index 0000000..5164bba
Binary files /dev/null and b/image/icons/24x24/CRM--Admin--Label.png differ
diff --git a/image/icons/24x24/CRM--Admin--Message.png b/image/icons/24x24/CRM--Admin--Message.png
new file mode 100644 (file)
index 0000000..bb8920f
Binary files /dev/null and b/image/icons/24x24/CRM--Admin--Message.png differ
diff --git a/image/icons/24x24/CRM--Admin--Mitteilungen.png b/image/icons/24x24/CRM--Admin--Mitteilungen.png
deleted file mode 100644 (file)
index bb8920f..0000000
Binary files a/image/icons/24x24/CRM--Admin--Mitteilungen.png and /dev/null differ
diff --git a/image/icons/24x24/CRM--Admin--User Groups.png b/image/icons/24x24/CRM--Admin--User Groups.png
new file mode 100644 (file)
index 0000000..b7875dc
Binary files /dev/null and b/image/icons/24x24/CRM--Admin--User Groups.png differ
diff --git a/image/icons/24x24/CRM--Admin--User.png b/image/icons/24x24/CRM--Admin--User.png
new file mode 100644 (file)
index 0000000..bfd6bc4
Binary files /dev/null and b/image/icons/24x24/CRM--Admin--User.png differ
diff --git a/image/icons/24x24/CRM--Appointments.png b/image/icons/24x24/CRM--Appointments.png
new file mode 100644 (file)
index 0000000..9d4a78a
Binary files /dev/null and b/image/icons/24x24/CRM--Appointments.png differ
diff --git a/image/icons/24x24/CRM--Auftragschance.png b/image/icons/24x24/CRM--Auftragschance.png
deleted file mode 100644 (file)
index 61202dd..0000000
Binary files a/image/icons/24x24/CRM--Auftragschance.png and /dev/null differ
diff --git a/image/icons/24x24/CRM--Follow-Up.png b/image/icons/24x24/CRM--Follow-Up.png
new file mode 100644 (file)
index 0000000..bab2a92
Binary files /dev/null and b/image/icons/24x24/CRM--Follow-Up.png differ
diff --git a/image/icons/24x24/CRM--Help.png b/image/icons/24x24/CRM--Help.png
new file mode 100644 (file)
index 0000000..e42ab44
Binary files /dev/null and b/image/icons/24x24/CRM--Help.png differ
diff --git a/image/icons/24x24/CRM--Hilfe.png b/image/icons/24x24/CRM--Hilfe.png
deleted file mode 100644 (file)
index e42ab44..0000000
Binary files a/image/icons/24x24/CRM--Hilfe.png and /dev/null differ
diff --git a/image/icons/24x24/CRM--Knowledge.png b/image/icons/24x24/CRM--Knowledge.png
new file mode 100644 (file)
index 0000000..ab43942
Binary files /dev/null and b/image/icons/24x24/CRM--Knowledge.png differ
diff --git a/image/icons/24x24/CRM--Kunden.png b/image/icons/24x24/CRM--Kunden.png
deleted file mode 100644 (file)
index 644a6f5..0000000
Binary files a/image/icons/24x24/CRM--Kunden.png and /dev/null differ
diff --git a/image/icons/24x24/CRM--Lieferant.png b/image/icons/24x24/CRM--Lieferant.png
deleted file mode 100644 (file)
index 40b1ce0..0000000
Binary files a/image/icons/24x24/CRM--Lieferant.png and /dev/null differ
diff --git a/image/icons/24x24/CRM--Memo.png b/image/icons/24x24/CRM--Memo.png
new file mode 100644 (file)
index 0000000..e19987a
Binary files /dev/null and b/image/icons/24x24/CRM--Memo.png differ
diff --git a/image/icons/24x24/CRM--Notizen.png b/image/icons/24x24/CRM--Notizen.png
deleted file mode 100644 (file)
index e19987a..0000000
Binary files a/image/icons/24x24/CRM--Notizen.png and /dev/null differ
diff --git a/image/icons/24x24/CRM--Opportunity.png b/image/icons/24x24/CRM--Opportunity.png
new file mode 100644 (file)
index 0000000..61202dd
Binary files /dev/null and b/image/icons/24x24/CRM--Opportunity.png differ
diff --git a/image/icons/24x24/CRM--Personen.png b/image/icons/24x24/CRM--Personen.png
deleted file mode 100644 (file)
index b0a9b19..0000000
Binary files a/image/icons/24x24/CRM--Personen.png and /dev/null differ
diff --git a/image/icons/24x24/CRM--Schnellsuche.png b/image/icons/24x24/CRM--Schnellsuche.png
deleted file mode 100644 (file)
index c901831..0000000
Binary files a/image/icons/24x24/CRM--Schnellsuche.png and /dev/null differ
diff --git a/image/icons/24x24/CRM--Search.png b/image/icons/24x24/CRM--Search.png
new file mode 100644 (file)
index 0000000..c901831
Binary files /dev/null and b/image/icons/24x24/CRM--Search.png differ
diff --git a/image/icons/24x24/CRM--Termine.png b/image/icons/24x24/CRM--Termine.png
deleted file mode 100644 (file)
index 9d4a78a..0000000
Binary files a/image/icons/24x24/CRM--Termine.png and /dev/null differ
diff --git a/image/icons/24x24/CRM--Wiedervorlage.png b/image/icons/24x24/CRM--Wiedervorlage.png
deleted file mode 100644 (file)
index bab2a92..0000000
Binary files a/image/icons/24x24/CRM--Wiedervorlage.png and /dev/null differ
diff --git a/image/icons/24x24/CRM--Wissens-DB.png b/image/icons/24x24/CRM--Wissens-DB.png
deleted file mode 100644 (file)
index ab43942..0000000
Binary files a/image/icons/24x24/CRM--Wissens-DB.png and /dev/null differ
diff --git a/image/icons/32x32/CRM--Add--Customer.png b/image/icons/32x32/CRM--Add--Customer.png
new file mode 100644 (file)
index 0000000..19b4390
Binary files /dev/null and b/image/icons/32x32/CRM--Add--Customer.png differ
diff --git a/image/icons/32x32/CRM--Add--Person.png b/image/icons/32x32/CRM--Add--Person.png
new file mode 100644 (file)
index 0000000..f197c86
Binary files /dev/null and b/image/icons/32x32/CRM--Add--Person.png differ
diff --git a/image/icons/32x32/CRM--Add--Vendor.png b/image/icons/32x32/CRM--Add--Vendor.png
new file mode 100644 (file)
index 0000000..70cb910
Binary files /dev/null and b/image/icons/32x32/CRM--Add--Vendor.png differ
diff --git a/image/icons/32x32/CRM--Admin--Benutzer.png b/image/icons/32x32/CRM--Admin--Benutzer.png
deleted file mode 100644 (file)
index 60e6685..0000000
Binary files a/image/icons/32x32/CRM--Admin--Benutzer.png and /dev/null differ
diff --git a/image/icons/32x32/CRM--Admin--Document Template.png b/image/icons/32x32/CRM--Admin--Document Template.png
new file mode 100644 (file)
index 0000000..a38f0dc
Binary files /dev/null and b/image/icons/32x32/CRM--Admin--Document Template.png differ
diff --git a/image/icons/32x32/CRM--Admin--Dokumentvorlage.png b/image/icons/32x32/CRM--Admin--Dokumentvorlage.png
deleted file mode 100644 (file)
index a38f0dc..0000000
Binary files a/image/icons/32x32/CRM--Admin--Dokumentvorlage.png and /dev/null differ
diff --git a/image/icons/32x32/CRM--Admin--Etiketten.png b/image/icons/32x32/CRM--Admin--Etiketten.png
deleted file mode 100644 (file)
index 443782b..0000000
Binary files a/image/icons/32x32/CRM--Admin--Etiketten.png and /dev/null differ
diff --git a/image/icons/32x32/CRM--Admin--Gruppen.png b/image/icons/32x32/CRM--Admin--Gruppen.png
deleted file mode 100644 (file)
index 0523718..0000000
Binary files a/image/icons/32x32/CRM--Admin--Gruppen.png and /dev/null differ
diff --git a/image/icons/32x32/CRM--Admin--Label.png b/image/icons/32x32/CRM--Admin--Label.png
new file mode 100644 (file)
index 0000000..443782b
Binary files /dev/null and b/image/icons/32x32/CRM--Admin--Label.png differ
diff --git a/image/icons/32x32/CRM--Admin--Message.png b/image/icons/32x32/CRM--Admin--Message.png
new file mode 100644 (file)
index 0000000..f485558
Binary files /dev/null and b/image/icons/32x32/CRM--Admin--Message.png differ
diff --git a/image/icons/32x32/CRM--Admin--Mitteilungen.png b/image/icons/32x32/CRM--Admin--Mitteilungen.png
deleted file mode 100644 (file)
index f485558..0000000
Binary files a/image/icons/32x32/CRM--Admin--Mitteilungen.png and /dev/null differ
diff --git a/image/icons/32x32/CRM--Admin--User Groups.png b/image/icons/32x32/CRM--Admin--User Groups.png
new file mode 100644 (file)
index 0000000..0523718
Binary files /dev/null and b/image/icons/32x32/CRM--Admin--User Groups.png differ
diff --git a/image/icons/32x32/CRM--Admin--User.png b/image/icons/32x32/CRM--Admin--User.png
new file mode 100644 (file)
index 0000000..60e6685
Binary files /dev/null and b/image/icons/32x32/CRM--Admin--User.png differ
diff --git a/image/icons/32x32/CRM--Appointments.png b/image/icons/32x32/CRM--Appointments.png
new file mode 100644 (file)
index 0000000..fb78e1e
Binary files /dev/null and b/image/icons/32x32/CRM--Appointments.png differ
diff --git a/image/icons/32x32/CRM--Auftragschance.png b/image/icons/32x32/CRM--Auftragschance.png
deleted file mode 100644 (file)
index e9a4594..0000000
Binary files a/image/icons/32x32/CRM--Auftragschance.png and /dev/null differ
diff --git a/image/icons/32x32/CRM--Follow-Up.png b/image/icons/32x32/CRM--Follow-Up.png
new file mode 100644 (file)
index 0000000..68ad6fb
Binary files /dev/null and b/image/icons/32x32/CRM--Follow-Up.png differ
diff --git a/image/icons/32x32/CRM--Help.png b/image/icons/32x32/CRM--Help.png
new file mode 100644 (file)
index 0000000..0b39887
Binary files /dev/null and b/image/icons/32x32/CRM--Help.png differ
diff --git a/image/icons/32x32/CRM--Hilfe.png b/image/icons/32x32/CRM--Hilfe.png
deleted file mode 100644 (file)
index 0b39887..0000000
Binary files a/image/icons/32x32/CRM--Hilfe.png and /dev/null differ
diff --git a/image/icons/32x32/CRM--Knowledge.png b/image/icons/32x32/CRM--Knowledge.png
new file mode 100644 (file)
index 0000000..fe582b9
Binary files /dev/null and b/image/icons/32x32/CRM--Knowledge.png differ
diff --git a/image/icons/32x32/CRM--Kunden.png b/image/icons/32x32/CRM--Kunden.png
deleted file mode 100644 (file)
index 19b4390..0000000
Binary files a/image/icons/32x32/CRM--Kunden.png and /dev/null differ
diff --git a/image/icons/32x32/CRM--Lieferant.png b/image/icons/32x32/CRM--Lieferant.png
deleted file mode 100644 (file)
index 70cb910..0000000
Binary files a/image/icons/32x32/CRM--Lieferant.png and /dev/null differ
diff --git a/image/icons/32x32/CRM--Memo.png b/image/icons/32x32/CRM--Memo.png
new file mode 100644 (file)
index 0000000..a838a7b
Binary files /dev/null and b/image/icons/32x32/CRM--Memo.png differ
diff --git a/image/icons/32x32/CRM--Notizen.png b/image/icons/32x32/CRM--Notizen.png
deleted file mode 100644 (file)
index a838a7b..0000000
Binary files a/image/icons/32x32/CRM--Notizen.png and /dev/null differ
diff --git a/image/icons/32x32/CRM--Opportunity.png b/image/icons/32x32/CRM--Opportunity.png
new file mode 100644 (file)
index 0000000..e9a4594
Binary files /dev/null and b/image/icons/32x32/CRM--Opportunity.png differ
diff --git a/image/icons/32x32/CRM--Personen.png b/image/icons/32x32/CRM--Personen.png
deleted file mode 100644 (file)
index f197c86..0000000
Binary files a/image/icons/32x32/CRM--Personen.png and /dev/null differ
diff --git a/image/icons/32x32/CRM--Schnellsuche.png b/image/icons/32x32/CRM--Schnellsuche.png
deleted file mode 100644 (file)
index 8db93f8..0000000
Binary files a/image/icons/32x32/CRM--Schnellsuche.png and /dev/null differ
diff --git a/image/icons/32x32/CRM--Search.png b/image/icons/32x32/CRM--Search.png
new file mode 100644 (file)
index 0000000..8db93f8
Binary files /dev/null and b/image/icons/32x32/CRM--Search.png differ
diff --git a/image/icons/32x32/CRM--Termine.png b/image/icons/32x32/CRM--Termine.png
deleted file mode 100644 (file)
index fb78e1e..0000000
Binary files a/image/icons/32x32/CRM--Termine.png and /dev/null differ
diff --git a/image/icons/32x32/CRM--Wiedervorlage.png b/image/icons/32x32/CRM--Wiedervorlage.png
deleted file mode 100644 (file)
index 68ad6fb..0000000
Binary files a/image/icons/32x32/CRM--Wiedervorlage.png and /dev/null differ
diff --git a/image/icons/32x32/CRM--Wissens-DB.png b/image/icons/32x32/CRM--Wissens-DB.png
deleted file mode 100644 (file)
index fe582b9..0000000
Binary files a/image/icons/32x32/CRM--Wissens-DB.png and /dev/null differ
index 6439455..9359ee5 100644 (file)
@@ -4,7 +4,7 @@ $(function(){
     $(dummy).autocomplete({
       source: function(req, rsp) {
         $.ajax({
-          url: 'controller.pl?action=Customer/ajax_autocomplete',
+          url: 'controller.pl?action=CustomerVendor/ajaj_customer_autocomplete',
           dataType: "json",
           data: {
             term: req.term,
@@ -21,5 +21,5 @@ $(function(){
         $(dummy).val(ui.item.name);
       },
     });
-  })
-})
+  });
+});
index 0a4886f..b89751e 100644 (file)
@@ -26,7 +26,9 @@ namespace('kivi', function(k){
     var state   = STATES.PICKED;
     var last_real = $real.val();
     var last_dummy = $dummy.val();
-    var open_dialog = function(){
+    var timer;
+
+    function open_dialog () {
       open_jqm_window({
         url: 'controller.pl?action=Part/part_picker_search',
         data: $.extend({
@@ -34,8 +36,9 @@ namespace('kivi', function(k){
         }, ajax_data($dummy.val())),
         id: 'part_selection',
       });
+      window.clearTimeout(timer);
       return true;
-    };
+    }
 
     function ajax_data(term) {
       var data = {
@@ -89,6 +92,11 @@ namespace('kivi', function(k){
       });
     };
 
+    function result_timer (event) {
+      window.clearTimeout(timer);
+      timer = window.setTimeout(update_results, 100);
+    }
+
     function close_popup() {
       $('#part_selection').jqmClose()
     };
@@ -156,7 +164,10 @@ namespace('kivi', function(k){
       }
     });
 
-//    $dummy.blur(make_defined_state);  // blur triggers also on open_jqm_dialog
+    $dummy.blur(function(){
+      window.clearTimeout(timer);
+      timer = window.setTimeout(make_defined_state, 100);
+    });
 
     // now add a picker div after the original input
     var pcont  = $('<span>').addClass('position-absolute');
@@ -173,6 +184,7 @@ namespace('kivi', function(k){
       convertible_unit: function() { return $convertible_unit },
       column:         function() { return $column },
       update_results: update_results,
+      result_timer:   result_timer,
       set_item:       set_item,
       reset:          make_defined_state,
       init_results:    function () {
index 71f1d31..904448d 100644 (file)
@@ -187,7 +187,23 @@ function open_jqm_window(params) {
 
 $(document).ready(function () {
   // initialize all jQuery UI tab elements:
-  $(".tabwidget").each(function(idx, element) { $(element).tabs(); });
+  $(".tabwidget").each(function(idx, element) {
+    var $element = $(element);
+    var tabsParams = {};
+
+    var elementId = $element.attr('id');
+    if( elementId ) {
+      var cookieName = 'jquery_ui_tab_'+ elementId;
+
+      tabsParams.active = $.cookie(cookieName);
+      tabsParams.activate = function(event, ui) {
+        var i = ui.newTab.parent().children().index(ui.newTab);
+        $.cookie(cookieName, i);
+      };
+    }
+
+    $element.tabs(tabsParams);
+  });
 
   $('input').focus(function(){
     if (focussable(this)) window.focused_element = this;
diff --git a/js/kivi.CustomerVendor.js b/js/kivi.CustomerVendor.js
new file mode 100644 (file)
index 0000000..aed7081
--- /dev/null
@@ -0,0 +1,170 @@
+namespace('kivi.CustomerVendor', function(ns) {
+
+  this.selectShipto = function(params) {
+    var shiptoId = $('#shipto_shipto_id').val();
+
+    if( shiptoId ) {
+      var url = 'controller.pl?action=CustomerVendor/ajaj_get_shipto&id='+ $('#cv_id').val() +'&db='+ $('#db').val() +'&shipto_id='+ shiptoId;
+
+      $.getJSON(url, function(data) {
+        for(var key in data)
+          $(document.getElementById('shipto_'+ key)).val(data[key]);
+
+        $('#action_delete_shipto').show();
+
+        if( params.onFormSet )
+          params.onFormSet();
+      });
+    }
+    else {
+      $('#shipto :input').not(':button, :submit, :reset, :hidden').val('');
+
+      $('#action_delete_shipto').hide();
+
+      if( params.onFormSet )
+        params.onFormSet();
+    }
+  };
+
+  this.selectDelivery = function(fromDate, toDate) {
+    var deliveryId = $('#delivery_id').val();
+
+    if( !deliveryId )
+      $("#delivery").empty();
+    else {
+      var url = 'controller.pl?action=CustomerVendor/get_delivery&id='+ $('#cv_id').val() +'&db='+ $('#db').val() +'&shipto_id='+ $('#delivery_id').val();
+
+      if( fromDate && toDate )
+        url += '&delivery_from='+ fromDate +'&delivery_to='+ toDate;
+
+      $('#delivery').load(url);
+    }
+  };
+
+  this.selectContact = function(params) {
+    var contactId = $('#contact_cp_id').val();
+
+    if( contactId ) {
+      var url = 'controller.pl?action=CustomerVendor/ajaj_get_contact&id='+ $('#cv_id').val() +'&db='+ $('#db').val() +'&contact_id='+ contactId;
+
+      $.getJSON(url, function(data) {
+        var contact = data.contact;
+        for(var key in contact)
+          $(document.getElementById('contact_'+ key)).val(contact[key])
+
+        var cvars = data.contact_cvars;
+        for(var key in cvars)
+          $(document.getElementById('contact_cvar_'+ key)).val(cvars[key]);
+
+        $('#action_delete_contact').show();
+
+        if( params.onFormSet )
+          params.onFormSet();
+      });
+    }
+    else {
+      $('#contacts :input').not(':button, :submit, :reset, :hidden').val('').removeAttr('checked').removeAttr('selected');
+
+      $('#action_delete_contact').hide();
+
+      if( params.onFormSet )
+        params.onFormSet();
+    }
+
+    $('#contact_cp_title_select, #contact_cp_abteilung_select').val('');
+  };
+
+  var mapSearchStmts = [
+    '#street',
+    ', ',
+    '#zipcode',
+    ' ',
+    '#city',
+    ', ',
+    '#country'
+  ];
+
+  this.MapWidget = function(prefix)
+  {
+    var $mapSearchElements = [];
+    var $widgetWrapper;
+
+    var init = function() {
+      if( $mapSearchElements.length > 0 )
+        return;
+
+      for(var i in mapSearchStmts) {
+        var stmt = mapSearchStmts[i];
+        if( stmt.charAt(0) == '#' ) {
+          var $elem = $('#'+ prefix + stmt.substring(1));
+          if( $elem )
+            $mapSearchElements.push($elem);
+        }
+      }
+    };
+
+    var isNotEmpty = function() {
+      for(var i in $mapSearchElements)
+        if( $mapSearchElements[i].val() == '' )
+          return false;
+      return true;
+    };
+
+    var showMap = function() {
+      var searchString = "";
+
+      for(var i in mapSearchStmts) {
+        var stmt = mapSearchStmts[i];
+        if( stmt.charAt(0) == '#' ) {
+          var val = $('#'+ prefix + stmt.substring(1)).val();
+          if( val )
+            searchString += val;
+        }
+        else
+          searchString += stmt;
+      }
+
+      var url = 'https://maps.google.com/maps?q='+ encodeURIComponent(searchString);
+
+      window.open(url, '_blank');
+      window.focus();
+    };
+
+    var render = function(widgetWrapper) {
+      init();
+
+      $widgetWrapper = $(widgetWrapper);
+
+      $widgetWrapper
+        .html('<img src="image/map.png" alt="'+ kivi.t8("Map") +'" title="'+ kivi.t8("Map") +'" />')
+        .click(function() {
+          showMap();
+        });
+      for(var i in $mapSearchElements)
+        $mapSearchElements[i].keyup(function() {
+          testInputs();
+        });
+      this.testInputs();
+    };
+
+    var testInputs = function() {
+      init();
+
+      if( isNotEmpty() )
+        $widgetWrapper.show();
+      else
+        $widgetWrapper.hide();
+    };
+
+    this.render = render;
+    this.testInputs = testInputs;
+  };
+
+  this.showHistoryWindow = function(id) {
+    var xPos = (screen.width - 800) / 2;
+    var yPos = (screen.height - 500) / 2;
+    var parm = "left="+ xPos +",top="+ yPos +",width=800,height=500,status=yes,scrollbars=yes";
+    var url = "common.pl?INPUT_ENCODING=UTF-8&action=show_history&longdescription=&input_name="+ encodeURIComponent(id);
+    window.open(url, "_new_generic", parm);
+  };
+});
index 0d45d30..883ac6b 100644 (file)
@@ -1,5 +1,6 @@
 namespace("kivi").setupLocale({
 "Are you sure?":"Sind Sie sicher?",
+"Map":"Karte",
 "The description is missing.":"Die Beschreibung fehlt.",
 "The name is missing.":"Der Name fehlt.",
 "The name must only consist of letters, numbers and underscores and start with a letter.":"Der Name darf nur aus Buchstaben (keine Umlaute), Ziffern und Unterstrichen bestehen und muss mit einem Buchstaben beginnen.",
index 272da98..e922e14 100755 (executable)
@@ -113,7 +113,6 @@ $self->{texts} = {
   'Accounting method'           => 'Versteuerungsart',
   'Accrual'                     => 'Soll-Versteuerung',
   'Accrual accounting'          => 'Soll-Versteuerung',
-  'Actions'                     => 'Aktionen',
   'Active'                      => 'Aktiv',
   'Active?'                     => 'Aktiviert?',
   'Add'                         => 'Erfassen',
@@ -138,9 +137,11 @@ $self->{texts} = {
   'Add Group'                   => 'Warengruppe erfassen',
   'Add Language'                => 'Sprache hinzufügen',
   'Add Lead'                    => 'Kundenquelle erfassen',
+  'Add Machine'                 => 'Maschine erfassen',
   'Add Part'                    => 'Ware erfassen',
   'Add Price Factor'            => 'Preisfaktor erfassen',
   'Add Pricegroup'              => 'Preisgruppe erfassen',
+  'Add Printer'                 => 'Drucker hinzufügen',
   'Add Project'                 => 'Projekt erfassen',
   'Add Purchase Delivery Order' => 'Lieferschein (Einkauf) erfassen',
   'Add Purchase Order'          => 'Lieferantenauftrag erfassen',
@@ -151,6 +152,7 @@ $self->{texts} = {
   'Add Sales Invoice'           => 'Rechnung erfassen',
   'Add Sales Order'             => 'Auftrag erfassen',
   'Add Service'                 => 'Dienstleistung erfassen',
+  'Add Service Contract'        => 'Wartungsvertrag erfassen',
   'Add Storno Credit Note'      => 'Gutschrift Storno hinzufügen',
   'Add Transaction'             => 'Dialogbuchen',
   'Add User'                    => 'Neuer Benutzer',
@@ -166,9 +168,9 @@ $self->{texts} = {
   'Add new currency'            => 'Neue Währung hinzufügen',
   'Add new custom variable'     => 'Neue benutzerdefinierte Variable erfassen',
   'Add note'                    => 'Notiz erfassen',
-  'Add printer'                 => 'Drucker hinzufügen',
   'Add unit'                    => 'Einheit hinzuf&uuml;gen',
   'Address'                     => 'Adresse',
+  'Admin'                       => 'Administration',
   'Administration'              => 'Administration',
   'Administration area'         => 'Administration',
   'Advance turnover tax return' => 'Umsatzsteuervoranmeldung',
@@ -206,6 +208,8 @@ $self->{texts} = {
   'Apply to all parts'          => 'Bei allen Artikeln setzen',
   'Apply to parts without buchungsgruppe' => 'Bei allen Artikeln ohne gültige Buchungsgruppe setzen',
   'Applying #1:'                => 'Führe #1 aus:',
+  'Appointment Category'        => 'Termin Kategorie',
+  'Appointments'                => 'Termine',
   'Approximately #1 prices will be updated.' => 'Ungefähr #1 Preise werden aktualisiert.',
   'Apr'                         => 'Apr',
   'April'                       => 'April',
@@ -335,6 +339,7 @@ $self->{texts} = {
   'CB Transaction'              => 'SB-Buchung',
   'CB Transactions'             => 'SB-Buchungen',
   'CR'                          => 'H',
+  'CRM'                         => 'CRM',
   'CRM admin'                   => 'Administration',
   'CRM create customers, vendors and contacts' => 'Erfassen (Kunden, Lieferanten, Personen)',
   'CRM follow up'               => 'Wiedervorlage',
@@ -344,7 +349,7 @@ $self->{texts} = {
   'CRM optional software'       => 'CRM optionale Software',
   'CRM other'                   => 'alles Andere',
   'CRM search'                  => 'Adresssuche',
-  'CRM send email'              => 'eMail',
+  'CRM send email'              => 'E-Mail',
   'CRM services'                => 'Dienstleistung',
   'CRM status'                  => 'Admin Status',
   'CRM termin'                  => 'Termine',
@@ -585,6 +590,7 @@ $self->{texts} = {
   'DATEX - Export Assistent'    => 'DATEV-Exportassistent',
   'DELETED'                     => 'Gelöscht',
   'DFV-Kennzeichen'             => 'DFV-Kennzeichen',
+  'DHL'                         => 'DHL',
   'DR'                          => 'S',
   'DUNNING STARTED'             => 'Mahnprozess gestartet',
   'DUNS number'                 => 'DUNS-Nummer',
@@ -594,8 +600,10 @@ $self->{texts} = {
   'Database Connection Test'    => 'Test der Datenbankverbindung',
   'Database Host'               => 'Datenbankcomputer',
   'Database ID'                 => 'Datenbank-ID',
+  'Database Management'         => 'Datenbankadministration',
   'Database User'               => 'Datenbankbenutzer',
   'Database host and port'      => 'Datenbankhost und -port',
+  'Database login (#1)'         => 'Datenbankanmeldung (#1)',
   'Database name'               => 'Datenbankname',
   'Database settings'           => 'Datenbankeinstellungen',
   'Database template'           => 'Datenbankvorlage',
@@ -707,8 +715,10 @@ $self->{texts} = {
   'Do you want to store the existing onhand values into a new warehouse?' => 'M&ouml;chten Sie die vorhandenen Mengendaten in ein Lager &uuml;bertragen?',
   'Document'                    => 'Dokument',
   'Document Project Number'     => 'Projektnummer des Belegs',
+  'Document Template'           => 'Dokumentvorlage',
   'Documentation'               => 'Dokumentation',
   'Documentation (in German)'   => 'Dokumentation',
+  'Documents'                   => 'Dokumente',
   'Documents in the WebDAV repository' => 'Dokumente im WebDAV-Repository',
   'Done'                        => 'Fertig',
   'Double partnumbers'          => 'Doppelte Artikelnummern',
@@ -739,8 +749,8 @@ $self->{texts} = {
   'Duplicate in CSV file'       => 'Duplikat in CSV-Datei',
   'Duplicate in database'       => 'Duplikat in Datenbank',
   'During the next update a taxkey 0 with tax rate of 0 will automatically created.' => 'Beim nächsten Ausführen des Updates wird ein Steuerschlüssel 0 mit einem Steuersatz von 0% automatisch erzeugt.',
-  'E-mail'                      => 'eMail',
-  'E-mail Statement to'         => 'Fälligkeitsabrechnung als eMail an',
+  'E-mail'                      => 'E-Mail',
+  'E-mail Statement to'         => 'Fälligkeitsabrechnung als E-Mail an',
   'E-mail address missing!'     => 'E-Mail-Adresse fehlt!',
   'EAN'                         => 'EAN',
   'EAN-Code'                    => 'EAN-Code',
@@ -860,6 +870,7 @@ $self->{texts} = {
   'Ertrag'                      => 'Ertrag',
   'Ertrag prozentual'           => 'Ertrag prozentual',
   'Escape character'            => 'Escape-Zeichen',
+  'Everyone can log in.'        => 'Alle können sich anmelden.',
   'Exact'                       => 'Genau',
   'Example: http://kivitendo.de' => 'Beispiel:  http://kivitendo.de',
   'Excel'                       => 'Excel',
@@ -997,6 +1008,7 @@ $self->{texts} = {
   'Help Template Variables'     => 'Hilfe zu Dokumenten-Variablen',
   'Help on column names'        => 'Hilfe zu Spaltennamen',
   'Here'                        => 'Hier',
+  'Here you only provide the credentials for logging into the database.' => 'Hier geben Sie nur die Logindaten für die Anmeldung an der Datenbank ein.',
   'Here\'s an example command line:' => 'Hier ist eine Kommandozeile, die als Beispiel dient:',
   'Hide Filter'                 => 'Filter verbergen',
   'Hide by default'             => 'Standardm&auml;&szlig;ig verstecken',
@@ -1024,6 +1036,7 @@ $self->{texts} = {
   'If the default transfer out always succeed use this bin for negative stock quantity.' => 'Standardlagerplatz für Auslagern ohne Prüfung auf Bestand',
   'If you enter values for the part number and / or part description then only those bins containing parts whose part number or part description match your input will be shown.' => 'Wenn Sie f&uuml;r die Artikelnummer und / oder die Beschreibung etwas eingeben, so werden nur die Lagerpl&auml;tze angezeigt, in denen Waren eingelagert sind, die Ihre Suchbegriffe enthalten.',
   'If you have not chosen for example the category revenue for a tax and you choose an revenue account to create a transfer in the general ledger, this tax will not be displayed in the tax dropdown.' => 'Wenn Sie z.B. die Kategory Erlös für eine Steuer nicht gewählt haben und ein Erlöskonto beim Erstellen einer Dialogbuchung wählen, wird diese Steuer auch nicht im Dropdown-Menü für die Steuern angezeigt.',
+  'If you lock the system normal users won\'t be able to log in.' => 'Wenn Sie das System sperren, so werden sich normale Benutzer nicht mehr anmelden können.',
   'If you see this message, you most likely just setup your LX-Office and haven\'t added any entry types. If this is the case, the option is accessible for administrators in the System menu.' => 'Wenn Sie diese Meldung sehen haben Sie wahrscheinlich ein frisches LX-Office Setup und noch keine Buchungsgruppen eingerichtet. Ein Administrator kann dies im Systemmen&uuml; erledigen.',
   'If you select a base unit then you also have to enter a factor.' => 'Wenn Sie eine Basiseinheit auswählen, dann müssen Sie auch einen Faktor eingeben.',
   'If you want to change any of these parameters then press the "Back" button, edit the file "config/kivitendo.conf" and login into the admin module again.' => 'Wenn Sie einen der Parameter Ã¤ndern wollen, so drücken Sie auf den "Zurück"-Button, bearbeiten Sie die Datei "config/kivitendo.conf", und melden Sie sich erneut im Administrationsbereich an.',
@@ -1130,11 +1143,13 @@ $self->{texts} = {
   'KNE-Export erfolgreich!'     => 'KNE-Export erfolgreich!',
   'KNr. beim Kunden'            => 'KNr. beim Kunden',
   'Keine Suchergebnisse gefunden!' => 'Keine Suchergebnisse gefunden!',
+  'Knowledge'                   => 'Wissen',
   'Konten'                      => 'Konten',
   'L'                           => 'L',
   'LIABILITIES'                 => 'PASSIVA',
   'LP'                          => 'LP',
   'LaTeX Templates'             => 'LaTeX-Vorlagen',
+  'Label'                       => 'Etikett',
   'Landscape'                   => 'Querformat',
   'Language'                    => 'Sprache',
   'Language (database ID)'      => 'Sprache (Datenbank-ID)',
@@ -1178,7 +1193,9 @@ $self->{texts} = {
   'List Accounts'               => 'Konten anzeigen',
   'List Languages'              => 'Sprachen anzeigen',
   'List Price'                  => 'Listenpreis',
+  'List Printers'               => 'Drucker anzeigen',
   'List Transactions'           => 'Buchungsliste',
+  'List Users, Clients and User Groups' => 'Benutzer, Mandanten und Benutzergruppen anzeigen',
   'List current background jobs' => 'Aktuelle Hintergrund-Jobs anzeigen',
   'List export'                 => 'Export anzeigen',
   'List of bank accounts'       => 'Liste der Bankkonten',
@@ -1191,6 +1208,7 @@ $self->{texts} = {
   'Loading...'                  => 'Wird geladen...',
   'Local Tax Office Preferences' => 'Angaben zum Finanzamt',
   'Lock System'                 => 'System sperren',
+  'Lock and unlock installation' => 'Installation sperren/entsperren',
   'Lock file handling failed. Please verify that the directory "#1" is writeable by the webserver.' => 'Die Lockdateibehandlung schlug fehl. Bitte stellen Sie sicher, dass der Webserver das Verzeichnis "#1" beschreiben darf.',
   'Lockfile created!'           => 'System gesperrt!',
   'Lockfile removed!'           => 'System entsperrt!',
@@ -1203,6 +1221,7 @@ $self->{texts} = {
   'Long Description'            => 'Langtext',
   'MAILED'                      => 'Gesendet',
   'MD'                          => 'PT',
+  'Machine'                     => 'Maschine',
   'Main Preferences'            => 'Grundeinstellungen',
   'Main sorting'                => 'Hauptsortierung',
   'Make'                        => 'Lieferant',
@@ -1230,7 +1249,7 @@ $self->{texts} = {
   'Maximum future booking interval' => 'Maximale Anzahl von Tagen an denen Buchungen in der Zukunft erlaubt sind.',
   'May'                         => 'Mai',
   'May '                        => 'Mai',
-  'May set the BCC field when sending emails' => 'Beim Verschicken von Emails das Feld \'BCC\' setzen',
+  'May set the BCC field when sending emails' => 'Beim Verschicken von E-Mails das Feld \'BCC\' setzen',
   'Meaning'                     => 'Bedeutung',
   'Medium Number'               => 'Datentr&auml;gernummer',
   'Memo'                        => 'Memo',
@@ -1331,6 +1350,7 @@ $self->{texts} = {
   'No warehouse has been created yet or the quantity of the bins is not configured yet.' => 'Es wurde noch kein Lager angelegt, bzw. die dazugehörigen Lagerplätze sind noch nicht konfiguriert.',
   'No.'                         => 'Position',
   'None'                        => 'Kein',
+  'Normal users cannot log in.' => 'Normale Benutzer können sich nicht anmelden.',
   'Not Discountable'            => 'Nicht rabattierfähig',
   'Not delivered'               => 'Nicht geliefert',
   'Not done yet'                => 'Noch nicht fertig',
@@ -1346,6 +1366,7 @@ $self->{texts} = {
   'Nothing has been selected for transfer.' => 'Es wurde nichts zum Umlagern ausgew&auml;hlt.',
   'Nothing selected!'           => 'Es wurde nichts ausgewählt!',
   'Nothing stocked yet.'        => 'Noch nichts eingelagert.',
+  'Nothing will be created or deleted at this stage!' => 'In diesem Schritt wird nichts angelegt oder gelöscht!',
   'Nov'                         => 'Nov',
   'November'                    => 'November',
   'Number'                      => 'Nummer',
@@ -1382,6 +1403,7 @@ $self->{texts} = {
   'Open this Website'           => 'Homepage in neuem Fenster &ouml;ffnen',
   'OpenDocument/OASIS'          => 'OpenDocument/OASIS',
   'Openings'                    => 'Öffnungszeiten',
+  'Opportunity'                 => 'Auftragschance',
   'Optional comment'            => 'Optionaler Kommentar',
   'Options'                     => 'Optionen',
   'Or download the whole Installation Documentation as PDF (350kB) for off-line study (currently in German Language): ' => 'Oder laden Sie die komplette Installationsbeschreibung als PDF (350kB) herunter: ',
@@ -1468,8 +1490,8 @@ $self->{texts} = {
   'Periodic invoices inactive'  => 'Wiederkehrende Rechnungen inaktiv',
   'Periodicity'                 => 'Periodizität',
   'Perpetual inventory'         => 'Bestandsmethode',
+  'Person'                      => 'Person',
   'Personal settings'           => 'Pers&ouml;nliche Einstellungen',
-  'Pg Database Administration'  => 'Datenbankadministration',
   'Phone'                       => 'Telefon',
   'Phone1'                      => 'Telefon 1 ',
   'Phone2'                      => 'Telefon 2',
@@ -1559,7 +1581,7 @@ $self->{texts} = {
   'Printer Management'          => 'Druckeradministration',
   'Printer management'          => 'Druckerverwaltung',
   'Printing ... '               => 'Es wird gedruckt.',
-  'Private E-mail'              => 'Private eMail',
+  'Private E-mail'              => 'Private E-Mail',
   'Private Phone'               => 'Privates Tel.',
   'Problem'                     => 'Problem',
   'Produce Assembly'            => 'Erzeugnis fertigen',
@@ -1776,12 +1798,13 @@ $self->{texts} = {
   'Serial No.'                  => 'Seriennummer',
   'Serial Number'               => 'Seriennummer',
   'Service'                     => 'Dienstleistung',
+  'Service Contract'            => 'Wartungsvertrag',
   'Service Items'               => 'Dienstleistungen',
   'Service Number missing!'     => 'Dienstleistungsnummer fehlt!',
   'Service, assembly or part'   => 'Dienstleistung, Erzeugnis oder Ware',
   'Services'                    => 'Dienstleistungen',
   'Set Language Values'         => 'Spracheinstellungen',
-  'Set eMail text'              => 'eMail Text eingeben',
+  'Set eMail text'              => 'E-Mail Text eingeben',
   'Settings'                    => 'Einstellungen',
   'Setup Menu'                  => 'Menü-Variante',
   'Ship to'                     => 'Lieferadresse',
@@ -1977,6 +2000,7 @@ $self->{texts} = {
   '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.',
   'The action you\'ve chosen has not been executed because the document does not contain any item yet.' => 'Die von Ihnen ausgewählte Aktion wurde nicht ausgeführt, weil der Beleg noch keine Positionen enthält.',
+  'The administration area is always accessible.' => 'Der Administrationsbereich ist immer zugänglich.',
   'The application "#1" was not found on the system.' => 'Die Anwendung "#1" wurde auf dem System nicht gefunden.',
   'The assembly has been created.' => 'Das Erzeugnis wurde hergestellt.',
   'The assistant could not find anything wrong with #1. Maybe the problem has been solved in the meantime.' => 'Der Korrekturassistent konnte kein Problem bei #1 feststellen. Eventuell wurde das Problem in der Zwischenzeit bereits behoben.',
@@ -2062,6 +2086,8 @@ $self->{texts} = {
   'The following users will have access to this client' => 'Die folgenden Benutzer werden auf diesen Mandanten Zugriff haben',
   'The formula needs the following syntax:<br>For regular article:<br>Variablename= Variable Unit;<br>Variablename2= Variable2 Unit2;<br>...<br>###<br>Variable + ( Variable2 / Variable )<br><b>Please be beware of the spaces in the formula</b><br>' => 'Die Formeln m&uuml;ssen in der folgenden Syntax eingegeben werden:<br>Bei normalen Artikeln:<br>Variablenname = Variable Einheit;<br>Variablenname2 = Variable2 Einheit2;<br>...<br>###<br>Variable + Variable2 * ( Variable - Variable2 )<br>Variablennamen und Einheiten dürfen nur aus alphanumerischen Zeichen bestehen.<br>Es muss jeweils die Gesamte Zeile eingegeben werden',
   'The greetings have been saved.' => 'Die Anreden wurden gespeichert',
+  'The installation is currently locked.' => 'Die Installation ist momentan gesperrt.',
+  'The installation is currently unlocked.' => 'Die Installation ist momentan entsperrt.',
   'The items are imported accoring do their number "X" regardless of the column order inside the file.' => 'Die Einträge werden in der Reihenfolge ihrer Indizes "X" unabhängig von der Spaltenreihenfolge in der Datei importiert.',
   'The link target to add has been created from the existing record.' => 'Das auszuwählende Verknüpfungsziel wurde aus dem bestehenden Beleg erstellt.',
   'The list has been printed.'  => 'Die Liste wurde ausgedruckt.',
@@ -2188,7 +2214,6 @@ $self->{texts} = {
   'This group is valid for the following clients' => 'Diese Gruppe ist für die folgenden Mandanten gültig',
   'This has been changed in this version, therefore please change the "old" bins to some real warehouse bins.' => 'Das wurde in dieser Version umgestellt, bitte Ã¤ndern Sie die Freitext-Lagerplätze auf vorhandene Lagerplätze.',
   'This has been changed in this version.' => 'Ab dieser Version ist dies nicht mehr so.',
-  'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!' => 'In diesem Schritt werden bestehende Datenbanken gesucht. Es werden noch keine &Auml;nderungen vorgenommen!',
   'This is a very critical problem.' => 'Dieses Problem ist sehr schwerwiegend.',
   'This is the client to be selected by default on the login screen.' => 'Dies ist derjenige Mandant, der im Loginbildschirm standardmäßig ausgewählt sein wird.',
   'This is the default bin for ignoring onhand' => 'Standardlagerplatz für Auslagern ohne Bestandsprüfung',
@@ -2207,6 +2232,7 @@ $self->{texts} = {
   'This user will have access to the following clients' => 'Dieser Benutzer wird Zugriff auf die folgenden Mandanten haben',
   'This vendor number is already in use.' => 'Diese Lieferantennummer wird bereits verwendet.',
   'Three Options:'              => 'Drei Optionen:',
+  'Time Tracking'               => 'Zeiterfassung',
   'Time period for the analysis:' => 'Analysezeitraum:',
   'Timestamp'                   => 'Uhrzeit',
   'Title'                       => 'Titel',
@@ -2310,6 +2336,7 @@ $self->{texts} = {
   'Use master default bin for Default Transfer, if no default bin for the part is configured' => 'Standardlagerplatz für Ein- / Auslagern Ã¼ber Standard-Lagerplatz, falls für die Ware kein expliziter Lagerplatz konfiguriert ist',
   'User'                        => 'Benutzer',
   'User Config'                 => 'Einstellungen',
+  'User Groups'                 => 'Gruppen',
   'User Preferences'            => 'Benutzereinstellungen',
   'User access'                 => 'Benutzerzugriff',
   'User list'                   => 'Benutzerliste',
@@ -2320,6 +2347,7 @@ $self->{texts} = {
   'Users that have access to this client' => 'Benutzer mit Zugriff auf diesen Mandanten',
   'Users with access'           => 'Benutzer mit Zugriff',
   'Users with access to this client' => 'Benutzer mit Zugriff auf diesen Mandanten',
+  'Users, Clients and User Groups' => 'Benutzer, Mandanten und Benutzergruppen',
   'VAT ID'                      => 'UStdID-Nr',
   'Valid'                       => 'Gültig',
   'Valid from'                  => 'Gültig ab',
@@ -2495,8 +2523,9 @@ $self->{texts} = {
   'done'                        => 'erledigt',
   'down'                        => 'runter',
   'dunning_list'                => 'mahnungsliste',
-  'eMail Send?'                 => 'eMail-Versand?',
-  'eMail?'                      => 'eMail?',
+  'eBayImporter'                => 'eBay-Importierer',
+  'eMail Send?'                 => 'E-Mail-Versand?',
+  'eMail?'                      => 'E-Mail?',
   'ea'                          => 'St.',
   'emailed to'                  => 'gemailt an',
   'empty'                       => 'leer',
index 3424a01..38be9b3 100644 (file)
@@ -130,6 +130,7 @@ $self->{texts} = {
   'Add Group'                   => '',
   'Add Language'                => '',
   'Add Lead'                    => '',
+  'Add Machine'                 => '',
   'Add Part'                    => '',
   'Add Payment Terms'           => '',
   'Add Price Factor'            => '',
@@ -145,6 +146,7 @@ $self->{texts} = {
   'Add Sales Invoice'           => '',
   'Add Sales Order'             => '',
   'Add Service'                 => '',
+  'Add Service Contract'        => '',
   'Add Storno Credit Note'      => '',
   'Add Transaction'             => '',
   'Add User'                    => '',
@@ -197,6 +199,8 @@ $self->{texts} = {
   'Apply to all parts'          => '',
   'Apply to parts without buchungsgruppe' => '',
   'Applying #1:'                => '',
+  'Appointment Category'        => '',
+  'Appointments'                => '',
   'Approximately #1 prices will be updated.' => '',
   'Apr'                         => '',
   'April'                       => '',
@@ -658,6 +662,8 @@ $self->{texts} = {
   'Do you want to carry this shipping address over to the new purchase order so that the vendor can deliver the goods directly to your customer?' => '',
   'Do you want to store the existing onhand values into a new warehouse?' => '',
   'Document'                    => '',
+  'Document Template'           => '',
+  'Documents'                   => '',
   'Document Project Number'     => '',
   'Documents in the WebDAV repository' => '',
   'Done'                        => '',
@@ -1061,6 +1067,7 @@ $self->{texts} = {
   'L'                           => '',
   'LIABILITIES'                 => '',
   'LP'                          => '',
+  'Label'                       => '',
   'LaTeX Templates'             => '',
   'Landscape'                   => '',
   'Language'                    => '',
@@ -1130,6 +1137,7 @@ $self->{texts} = {
   'Long Dates'                  => '',
   'Long Description'            => '',
   'MAILED'                      => '',
+  'Machine'                     => '',
   'MSG_BROWSER_DOES_NOT_SUPPORT_IFRAMES' => '',
   'Main Preferences'            => '',
   'Main sorting'                => '',
@@ -1306,6 +1314,7 @@ $self->{texts} = {
   'OpenDocument/OASIS'          => '',
   'Openings'                    => '',
   'Optional comment'            => '',
+  'Opportunity'                 => '',
   'Options'                     => '',
   'Or download the whole Installation Documentation as PDF (350kB) for off-line study (currently in German Language): ' => '',
   'Order'                       => '',
@@ -1674,6 +1683,7 @@ $self->{texts} = {
   'Serial No.'                  => '',
   'Serial Number'               => '',
   'Service'                     => '',
+  'Service Contract'            => '',
   'Service Items'               => '',
   'Service Number missing!'     => '',
   'Service unit'                => '',
@@ -2028,6 +2038,7 @@ $self->{texts} = {
   'This upgrade script tries to map all existing units in the database to the newly created units.' => '',
   'This vendor number is already in use.' => '',
   'Time period for the analysis:' => '',
+  'Time Track'                  => '',
   'Timestamp'                   => '',
   'Title'                       => '',
   'To'                          => '',
@@ -2121,6 +2132,7 @@ $self->{texts} = {
   'Use Templates'               => '',
   'User'                        => '',
   'User Config'                 => '',
+  'User Groups'                 => '',
   'User Login'                  => '',
   'User data migration'         => '',
   'User deleted!'               => '',
@@ -2325,6 +2337,7 @@ $self->{texts} = {
   'kivitendo has found one or more problems in the general ledger.' => '',
   'kivitendo is about to update the database [ #1 ].' => '',
   'kivitendo is now able to manage warehouses instead of just tracking the amount of goods in your system.' => '',
+  'Knowledge'                   => '',
   'lead deleted!'               => '',
   'lead saved!'                 => '',
   'list'                        => '',
diff --git a/menu.ini b/menu.ini
deleted file mode 100644 (file)
index 5031c98..0000000
--- a/menu.ini
+++ /dev/null
@@ -1,722 +0,0 @@
-[Master Data]
-
-[Master Data--Add Customer]
-ACCESS=customer_vendor_edit
-module=ct.pl
-action=add
-db=customer
-
-[Master Data--Add Vendor]
-ACCESS=customer_vendor_edit
-module=ct.pl
-action=add
-db=vendor
-
-[Master Data--Add Part]
-ACCESS=part_service_assembly_edit
-module=ic.pl
-action=add
-item=part
-
-[Master Data--Add Service]
-ACCESS=part_service_assembly_edit
-module=ic.pl
-action=add
-item=service
-
-[Master Data--Add Assembly]
-ACCESS=part_service_assembly_edit
-module=ic.pl
-action=add
-item=assembly
-
-[Master Data--Add Project]
-ACCESS=project_edit
-module=controller.pl
-action=Project/new
-
-[Master Data--Update Prices]
-ACCESS=part_service_assembly_edit
-module=ic.pl
-action=search_update_prices
-
-
-[Master Data--Reports]
-module=menu.pl
-action=acc_menu
-submenu=1
-
-[Master Data--Reports--Customers]
-ACCESS=customer_vendor_edit
-module=ct.pl
-action=search
-db=customer
-
-[Master Data--Reports--Vendors]
-ACCESS=customer_vendor_edit
-module=ct.pl
-action=search
-db=vendor
-
-[Master Data--Reports--Contacts]
-ACCESS=customer_vendor_edit
-module=ct.pl
-action=search_contact
-
-[Master Data--Reports--Parts]
-ACCESS=part_service_assembly_details
-module=ic.pl
-action=search
-searchitems=part
-
-[Master Data--Reports--Services]
-ACCESS=part_service_assembly_details
-module=ic.pl
-action=search
-searchitems=service
-
-[Master Data--Reports--Assemblies]
-ACCESS=part_service_assembly_details
-module=ic.pl
-action=search
-searchitems=assembly
-
-[Master Data--Reports--Projects]
-ACCESS=project_edit
-module=controller.pl
-action=Project/search
-
-[AR]
-
-[AR--Add Quotation]
-ACCESS=sales_quotation_edit
-module=oe.pl
-action=add
-type=sales_quotation
-
-[AR--Add Sales Order]
-ACCESS=sales_order_edit
-module=oe.pl
-action=add
-type=sales_order
-
-[AR--Add Delivery Order]
-ACCESS=sales_delivery_order_edit
-module=do.pl
-action=add
-type=sales_delivery_order
-
-[AR--Add Sales Invoice]
-ACCESS=invoice_edit
-module=is.pl
-action=add
-type=invoice
-
-[AR--Add Credit Note]
-ACCESS=invoice_edit
-module=is.pl
-action=add
-type=credit_note
-
-[AR--Add Dunning]
-ACCESS=dunning_edit
-module=dn.pl
-action=add
-
-[AR--Reports]
-module=menu.pl
-action=acc_menu
-submenu=1
-
-[AR--Reports--Quotations]
-ACCESS=sales_quotation_edit
-module=oe.pl
-action=search
-type=sales_quotation
-
-[AR--Reports--Sales Orders]
-ACCESS=sales_order_edit
-module=oe.pl
-action=search
-type=sales_order
-
-[AR--Reports--Delivery Orders]
-ACCESS=sales_delivery_order_edit
-module=do.pl
-action=search
-type=sales_delivery_order
-
-[AR--Reports--Invoices, Credit Notes & AR Transactions]
-ACCESS=invoice_edit
-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
-action=search
-
-[AR--Reports--Delivery Plan]
-ACCESS=sales_order_edit
-module=controller.pl
-action=DeliveryPlan/list
-
-[AP]
-
-[AP--Add RFQ]
-ACCESS=request_quotation_edit
-module=oe.pl
-action=add
-type=request_quotation
-
-[AP--Add Purchase Order]
-ACCESS=purchase_order_edit
-module=oe.pl
-action=add
-type=purchase_order
-
-[AP--Add Delivery Note]
-ACCESS=purchase_delivery_order_edit
-module=do.pl
-action=add
-type=purchase_delivery_order
-
-[AP--Add Vendor Invoice]
-ACCESS=vendor_invoice_edit
-module=ir.pl
-action=add
-type=invoice
-
-
-[AP--Reports]
-module=menu.pl
-action=acc_menu
-submenu=1
-
-[AP--Reports--RFQs]
-ACCESS=request_quotation_edit
-module=oe.pl
-action=search
-type=request_quotation
-
-[AP--Reports--Purchase Orders]
-ACCESS=purchase_order_edit
-module=oe.pl
-action=search
-type=purchase_order
-
-[AP--Reports--Delivery Orders]
-ACCESS=purchase_delivery_order_edit
-module=do.pl
-action=search
-type=purchase_delivery_order
-
-[AP--Reports--Vendor Invoices & AP Transactions]
-ACCESS=vendor_invoice_edit
-module=ap.pl
-action=search
-nextsub=ap_transactions
-
-
-[Warehouse]
-
-[Warehouse--Stock]
-ACCESS=warehouse_management
-module=controller.pl
-action=Inventory/stock_in
-
-[Warehouse--Produce Assembly]
-ACCESS=warehouse_management
-module=wh.pl
-action=transfer_warehouse_selection
-trans_type=assembly
-
-[Warehouse--Transfer]
-ACCESS=warehouse_management
-module=wh.pl
-action=transfer_warehouse_selection
-trans_type=transfer
-
-[Warehouse--Removal]
-ACCESS=warehouse_management
-module=wh.pl
-action=transfer_warehouse_selection
-trans_type=removal
-
-[Warehouse--Reports]
-module=menu.pl
-action=acc_menu
-submenu=1
-
-[Warehouse--Reports--Warehouse content]
-ACCESS=warehouse_contents | warehouse_management
-module=wh.pl
-action=report
-
-[Warehouse--Reports--WHJournal]
-ACCESS=warehouse_management
-module=wh.pl
-action=journal
-
-
-[General Ledger]
-
-[General Ledger--Add Transaction]
-ACCESS=general_ledger
-module=gl.pl
-action=add
-
-[General Ledger--Add AR Transaction]
-ACCESS=general_ledger
-module=ar.pl
-action=add
-
-[General Ledger--Add AP Transaction]
-ACCESS=general_ledger
-module=ap.pl
-action=add
-
-[General Ledger--DATEV - Export Assistent]
-ACCESS=datev_export
-module=datev.pl
-action=export
-
-
-
-
-[General Ledger--Reports]
-module=menu.pl
-action=acc_menu
-submenu=1
-
-
-[General Ledger--Reports--AR Aging]
-ACCESS=general_ledger
-module=rp.pl
-action=report
-report=ar_aging
-
-
-[General Ledger--Reports--AP Aging]
-ACCESS=general_ledger
-module=rp.pl
-action=report
-report=ap_aging
-
-[General Ledger--Reports--Journal]
-ACCESS=general_ledger
-module=gl.pl
-action=search
-
-
-[Cash]
-ACCESS=cash
-
-[Cash--Receipt]
-module=cp.pl
-action=payment
-type=receipt
-vc=customer
-
-[Cash--Payment]
-module=cp.pl
-action=payment
-type=check
-vc=vendor
-
-[Cash--Reconciliation]
-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
-action=acc_menu
-submenu=1
-
-[Cash--Reports--Receipts]
-module=rp.pl
-action=report
-report=receipts
-
-[Cash--Reports--Payments]
-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]
-
-[Reports--Chart of Accounts]
-ACCESS=report
-module=ca.pl
-action=chart_of_accounts
-
-[Reports--Trial Balance]
-ACCESS=report
-module=rp.pl
-action=report
-report=trial_balance
-
-[Reports--Income Statement]
-ACCESS=report
-module=rp.pl
-action=report
-report=income_statement
-
-[Reports--BWA]
-ACCESS=report
-module=rp.pl
-action=report
-report=bwa
-
-[Reports--Balance Sheet]
-ACCESS=report
-module=rp.pl
-action=report
-report=balance_sheet
-
-[Reports--UStVa]
-ACCESS=advance_turnover_tax_return
-module=ustva.pl
-action=report
-
-[Reports--Projecttransactions]
-ACCESS=report
-module=rp.pl
-action=report
-report=projects
-
-
-[Batch Printing]
-ACCESS=batch_printing
-
-[Batch Printing--Sales Invoices]
-ACCESS=invoice_edit
-module=bp.pl
-action=search
-vc=customer
-type=invoice
-
-[Batch Printing--Sales Orders]
-ACCESS=sales_order_edit
-module=bp.pl
-action=search
-vc=customer
-type=sales_order
-
-[Batch Printing--Quotations]
-ACCESS=sales_quotation_edit
-module=bp.pl
-action=search
-vc=customer
-type=sales_quotation
-
-[Batch Printing--Packing Lists]
-ACCESS=invoice_edit | sales_order_edit
-module=bp.pl
-action=search
-vc=customer
-type=packing_list
-
-[Batch Printing--Purchase Orders]
-ACCESS=purchase_order_edit
-module=bp.pl
-action=search
-vc=vendor
-type=purchase_order
-
-[Batch Printing--RFQs]
-ACCESS=request_quotation_edit
-module=bp.pl
-action=search
-vc=vendor
-type=request_quotation
-
-[Batch Printing--Checks]
-ACCESS=cash
-module=bp.pl
-action=search
-vc=vendor
-type=check
-
-[Batch Printing--Receipts]
-ACCESS=cash
-module=bp.pl
-action=search
-vc=customer
-type=receipt
-
-
-[Productivity]
-ACCESS=productivity
-
-[Productivity--Show TODO list]
-module=todo.pl
-action=show_todo_list
-
-[Productivity--Add Follow-Up]
-module=fu.pl
-action=add
-
-[Productivity--Edit Access Rights]
-module=fu.pl
-action=edit_access_rights
-
-[Productivity--Reports]
-module=menu.pl
-action=acc_menu
-submenu=1
-
-[Productivity--Reports--Follow-Ups]
-module=fu.pl
-action=search
-
-
-[System]
-ACCESS=config
-
-[System--Client Configuration]
-ACCESS=admin
-module=controller.pl
-action=ClientConfig/edit
-
-[System--UStVa Einstellungen]
-module=ustva.pl
-action=config_step1
-
-[System--Edit Dunning]
-module=dn.pl
-action=edit_config
-
-[System--Chart of Accounts]
-module=menu.pl
-action=acc_menu
-submenu=1
-
-[System--Chart of Accounts--Add Account]
-module=am.pl
-action=add_account
-
-[System--Chart of Accounts--List Accounts]
-module=am.pl
-action=list_account
-
-[System--Buchungsgruppen]
-module=am.pl
-action=list_buchungsgruppe
-
-[System--Taxes]
-module=am.pl
-action=list_tax
-
-[System--Bank accounts]
-module=bankaccounts.pl
-action=bank_account_list
-
-[System--Groups]
-module=pe.pl
-action=search
-type=partsgroup
-
-[System--Pricegroups]
-module=pe.pl
-action=search
-type=pricegroup
-
-[System--Edit units]
-module=am.pl
-action=edit_units
-
-[System--Price Factors]
-module=am.pl
-action=list_price_factors
-
-[System--Departments]
-module=controller.pl
-action=Department/list
-
-[System--Types of Business]
-module=controller.pl
-action=Business/list
-
-[System--Leads]
-module=am.pl
-action=list_lead
-
-[System--Languages and translations]
-module=menu.pl
-action=acc_menu
-submenu=1
-
-[System--Languages and translations--Add Language]
-module=am.pl
-action=add_language
-
-[System--Languages and translations--List Languages]
-module=am.pl
-action=list_language
-
-[System--Languages and translations--Greetings]
-module=generictranslations.pl
-action=edit_greetings
-
-[System--Languages and translations--SEPA strings]
-module=generictranslations.pl
-action=edit_sepa_strings
-
-
-[System--Payment Terms]
-module=controller.pl
-action=PaymentTerm/list
-
-[System--Manage Custom Variables]
-module=controller.pl
-action=CustomVariableConfig/list
-
-[System--Warehouses]
-module=am.pl
-action=list_warehouses
-
-
-[System--Import CSV]
-module=menu.pl
-action=acc_menu
-submenu=1
-
-[System--Import CSV--Customers and vendors]
-module=controller.pl
-action=CsvImport/new
-profile.type=customers_vendors
-
-[System--Import CSV--Contacts]
-module=controller.pl
-action=CsvImport/new
-profile.type=contacts
-
-[System--Import CSV--Shipto]
-module=controller.pl
-action=CsvImport/new
-profile.type=addresses
-
-[System--Import CSV--Parts]
-module=controller.pl
-action=CsvImport/new
-profile.type=parts
-
-[System--Import CSV--Projects]
-module=controller.pl
-action=CsvImport/new
-profile.type=projects
-
-[System--Templates]
-ACCESS=admin
-module=menu.pl
-action=acc_menu
-submenu=1
-
-[System--Templates--HTML Templates]
-module=amtemplates.pl
-action=display_template_form
-type=templates
-format=html
-
-[System--Templates--LaTeX Templates]
-module=amtemplates.pl
-action=display_template_form
-type=templates
-format=tex
-
-[System--Templates--Stylesheet]
-module=amtemplates.pl
-action=display_template_form
-type=stylesheet
-
-[System--General Ledger Corrections]
-module=acctranscorrections.pl
-action=analyze_filter
-
-[System--Background jobs and task server]
-ACCESS=admin
-module=menu.pl
-action=acc_menu
-submenu=1
-
-[System--Background jobs and task server--List current background jobs]
-module=controller.pl
-action=BackgroundJob/list
-
-[System--Background jobs and task server--Background job history]
-module=controller.pl
-action=BackgroundJobHistory/list
-
-[System--Background jobs and task server--Task server control]
-module=controller.pl
-action=TaskServer/show
-
-[System--Audit Control]
-module=am.pl
-action=audit_control
-
-[System--History Search Engine]
-module=am.pl
-action=show_history_search
-
-[System--Employees]
-ACCESS=admin
-module=controller.pl
-action=Employee/list
-
-[Program]
-
-[Program--User Preferences]
-module=am.pl
-action=config
-
-[Program--Version]
-module=login.pl
-action=company_logo
-no_todo_list=1
-
-[Program--Administration area]
-ACCESS=display_admin_link
-module=controller.pl
-action=Admin/login
-
-[Program--Documentation (in German)]
-href=doc/kivitendo-Dokumentation.pdf
-target=_blank
-
-[Program--kivitendo website (external)]
-href=http://www.kivitendo.de/
-target=_blank
-
-[Program--Logout]
-module=controller.pl
-action=LoginScreen/logout
diff --git a/menus/admin.ini b/menus/admin.ini
new file mode 100644 (file)
index 0000000..3da5752
--- /dev/null
@@ -0,0 +1,59 @@
+[Users, Clients and User Groups]
+
+[Users, Clients and User Groups--List Users, Clients and User Groups]
+module=controller.pl
+action=Admin/show
+
+[Users, Clients and User Groups--Add User]
+module=controller.pl
+action=Admin/new_user
+
+[Users, Clients and User Groups--Add Client]
+module=controller.pl
+action=Admin/new_client
+
+[Users, Clients and User Groups--Add User Group]
+module=controller.pl
+action=Admin/new_group
+
+[Database Management]
+
+[Database Management--Create Dataset]
+module=controller.pl
+action=Admin/create_dataset_login
+
+[Database Management--Delete Dataset]
+module=controller.pl
+action=Admin/delete_dataset_login
+
+[Printer Management]
+
+[Printer Management--List Printers]
+module=controller.pl
+action=Admin/list_printers
+
+[Printer Management--Add Printer]
+module=controller.pl
+action=Admin/new_printer
+
+[System]
+
+[System--Lock and unlock installation]
+module=controller.pl
+action=Admin/show_lock
+
+[System--Documentation (in German)]
+href=doc/kivitendo-Dokumentation.pdf
+target=_blank
+
+[System--kivitendo website (external)]
+href=http://www.kivitendo.de/
+target=_blank
+
+[System--To user login]
+module=controller.pl
+action=LoginScreen/user_login
+
+[System--Logout]
+module=controller.pl
+action=Admin/logout
diff --git a/menus/crm.ini b/menus/crm.ini
new file mode 100644 (file)
index 0000000..fcb0acf
--- /dev/null
@@ -0,0 +1,120 @@
+[CRM]
+
+[CRM--Search]
+ACCESS=crm_search
+module=crm/getData.php
+
+[CRM--Add]
+submenu=1
+
+[CRM--Add--Customer]
+ACCESS=crm_new
+module=crm/firmen3.php
+Q=C
+
+[CRM--Add--Vendor]
+ACCESS=crm_new
+module=crm/firmen3.php
+Q=V
+
+[CRM--Add--Person]
+ACCESS=crm_new
+module=crm/personen3.php
+
+[CRM--Appointments]
+ACCESS=crm_termin
+module=crm/termin.php
+
+[CRM--Opportunity]
+ACCESS=crm_opportunity
+module=crm/opportunity.php
+
+[CRM--Follow-Up]
+ACCESS=crm_follow
+module=crm/wvl1.php
+
+[CRM--E-mail]
+ACCESS=crm_email
+module=crm/mail.php
+
+[CRM--Knowledge]
+ACCESS=crm_knowhow
+module=crm/wissen.php
+
+[CRM--Memo]
+ACCESS=crm_notices
+module=crm/postit.php
+
+[CRM--Documents]
+ACCESS=crm_other
+module=crm/dokument.php
+
+[CRM--Time Tracking]
+ACCESS=crm_service
+module=crm/timetrack.php
+
+[CRM--DHL]
+ACCESS=crm_otje
+module=crm/dhl.php
+
+[CRM--eBayImporter]
+ACCESS=crm_other
+module=crm/ebayImporter.php
+
+[CRM--Service]
+submenu=1
+
+[CRM--Service--Service Contract]
+ACCESS=crm_service
+module=crm/vertrag1.php
+
+[CRM--Service--Add Service Contract]
+ACCESS=crm_service
+module=crm/vertrag3.php
+
+[CRM--Service--Machine]
+ACCESS=crm_service
+module=crm/maschine1.php
+
+[CRM--Service--Add Machine]
+ACCESS=crm_service
+module=crm/maschine3.php
+
+[CRM--Admin]
+submenu=1
+
+[CRM--Admin--Document Template]
+ACCESS=crm_admin
+module=crm/dokument1.php
+
+[CRM--Admin--Label]
+ACCESS=crm_admin
+module=crm/aufkleber_def.php
+
+[CRM--Admin--Appointment Category]
+ACCESS=crm_admin
+module=crm/tcatedit.php
+
+[CRM--Admin--Message]
+ACCESS=crm_admin
+module=crm/user3.php
+
+[CRM--Admin--Client]
+ACCESS=crm_adminstatus
+module=crm/mandant.php
+
+[CRM--Admin--User Groups]
+ACCESS=crm_admin
+module=crm/user2.php
+
+[CRM--Admin--User]
+ACCESS=crm_adminuser
+module=crm/user1.php
+
+[CRM--Admin--DHL]
+ACCESS=crm_admin
+module=crm/dhladm.php
+
+[CRM--Admin--Status]
+ACCESS=crm_adminstatus
+module=crm/status.php
diff --git a/menus/erp.ini b/menus/erp.ini
new file mode 100644 (file)
index 0000000..b0bff61
--- /dev/null
@@ -0,0 +1,723 @@
+[Master Data]
+
+[Master Data--Add Customer]
+ACCESS=customer_vendor_edit
+module=controller.pl
+action=CustomerVendor/add
+db=customer
+
+[Master Data--Add Vendor]
+ACCESS=customer_vendor_edit
+module=controller.pl
+action=CustomerVendor/add
+db=vendor
+
+[Master Data--Add Part]
+ACCESS=part_service_assembly_edit
+module=ic.pl
+action=add
+item=part
+
+[Master Data--Add Service]
+ACCESS=part_service_assembly_edit
+module=ic.pl
+action=add
+item=service
+
+[Master Data--Add Assembly]
+ACCESS=part_service_assembly_edit
+module=ic.pl
+action=add
+item=assembly
+
+[Master Data--Add Project]
+ACCESS=project_edit
+module=controller.pl
+action=Project/new
+
+[Master Data--Update Prices]
+ACCESS=part_service_assembly_edit
+module=ic.pl
+action=search_update_prices
+
+
+[Master Data--Reports]
+module=menu.pl
+action=acc_menu
+submenu=1
+
+[Master Data--Reports--Customers]
+ACCESS=customer_vendor_edit
+module=controller.pl
+action=CustomerVendor/search
+db=customer
+
+[Master Data--Reports--Vendors]
+ACCESS=customer_vendor_edit
+module=controller.pl
+action=CustomerVendor/search
+db=vendor
+
+[Master Data--Reports--Contacts]
+ACCESS=customer_vendor_edit
+module=controller.pl
+action=CustomerVendor/search_contact
+db=customer
+
+[Master Data--Reports--Parts]
+ACCESS=part_service_assembly_details
+module=ic.pl
+action=search
+searchitems=part
+
+[Master Data--Reports--Services]
+ACCESS=part_service_assembly_details
+module=ic.pl
+action=search
+searchitems=service
+
+[Master Data--Reports--Assemblies]
+ACCESS=part_service_assembly_details
+module=ic.pl
+action=search
+searchitems=assembly
+
+[Master Data--Reports--Projects]
+ACCESS=project_edit
+module=controller.pl
+action=Project/search
+
+[AR]
+
+[AR--Add Quotation]
+ACCESS=sales_quotation_edit
+module=oe.pl
+action=add
+type=sales_quotation
+
+[AR--Add Sales Order]
+ACCESS=sales_order_edit
+module=oe.pl
+action=add
+type=sales_order
+
+[AR--Add Delivery Order]
+ACCESS=sales_delivery_order_edit
+module=do.pl
+action=add
+type=sales_delivery_order
+
+[AR--Add Sales Invoice]
+ACCESS=invoice_edit
+module=is.pl
+action=add
+type=invoice
+
+[AR--Add Credit Note]
+ACCESS=invoice_edit
+module=is.pl
+action=add
+type=credit_note
+
+[AR--Add Dunning]
+ACCESS=dunning_edit
+module=dn.pl
+action=add
+
+[AR--Reports]
+module=menu.pl
+action=acc_menu
+submenu=1
+
+[AR--Reports--Quotations]
+ACCESS=sales_quotation_edit
+module=oe.pl
+action=search
+type=sales_quotation
+
+[AR--Reports--Sales Orders]
+ACCESS=sales_order_edit
+module=oe.pl
+action=search
+type=sales_order
+
+[AR--Reports--Delivery Orders]
+ACCESS=sales_delivery_order_edit
+module=do.pl
+action=search
+type=sales_delivery_order
+
+[AR--Reports--Invoices, Credit Notes & AR Transactions]
+ACCESS=invoice_edit
+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
+action=search
+
+[AR--Reports--Delivery Plan]
+ACCESS=sales_order_edit
+module=controller.pl
+action=DeliveryPlan/list
+
+[AP]
+
+[AP--Add RFQ]
+ACCESS=request_quotation_edit
+module=oe.pl
+action=add
+type=request_quotation
+
+[AP--Add Purchase Order]
+ACCESS=purchase_order_edit
+module=oe.pl
+action=add
+type=purchase_order
+
+[AP--Add Delivery Note]
+ACCESS=purchase_delivery_order_edit
+module=do.pl
+action=add
+type=purchase_delivery_order
+
+[AP--Add Vendor Invoice]
+ACCESS=vendor_invoice_edit
+module=ir.pl
+action=add
+type=invoice
+
+
+[AP--Reports]
+module=menu.pl
+action=acc_menu
+submenu=1
+
+[AP--Reports--RFQs]
+ACCESS=request_quotation_edit
+module=oe.pl
+action=search
+type=request_quotation
+
+[AP--Reports--Purchase Orders]
+ACCESS=purchase_order_edit
+module=oe.pl
+action=search
+type=purchase_order
+
+[AP--Reports--Delivery Orders]
+ACCESS=purchase_delivery_order_edit
+module=do.pl
+action=search
+type=purchase_delivery_order
+
+[AP--Reports--Vendor Invoices & AP Transactions]
+ACCESS=vendor_invoice_edit
+module=ap.pl
+action=search
+nextsub=ap_transactions
+
+
+[Warehouse]
+
+[Warehouse--Stock]
+ACCESS=warehouse_management
+module=controller.pl
+action=Inventory/stock_in
+
+[Warehouse--Produce Assembly]
+ACCESS=warehouse_management
+module=wh.pl
+action=transfer_warehouse_selection
+trans_type=assembly
+
+[Warehouse--Transfer]
+ACCESS=warehouse_management
+module=wh.pl
+action=transfer_warehouse_selection
+trans_type=transfer
+
+[Warehouse--Removal]
+ACCESS=warehouse_management
+module=wh.pl
+action=transfer_warehouse_selection
+trans_type=removal
+
+[Warehouse--Reports]
+module=menu.pl
+action=acc_menu
+submenu=1
+
+[Warehouse--Reports--Warehouse content]
+ACCESS=warehouse_contents | warehouse_management
+module=wh.pl
+action=report
+
+[Warehouse--Reports--WHJournal]
+ACCESS=warehouse_management
+module=wh.pl
+action=journal
+
+
+[General Ledger]
+
+[General Ledger--Add Transaction]
+ACCESS=general_ledger
+module=gl.pl
+action=add
+
+[General Ledger--Add AR Transaction]
+ACCESS=general_ledger
+module=ar.pl
+action=add
+
+[General Ledger--Add AP Transaction]
+ACCESS=general_ledger
+module=ap.pl
+action=add
+
+[General Ledger--DATEV - Export Assistent]
+ACCESS=datev_export
+module=datev.pl
+action=export
+
+
+
+
+[General Ledger--Reports]
+module=menu.pl
+action=acc_menu
+submenu=1
+
+
+[General Ledger--Reports--AR Aging]
+ACCESS=general_ledger
+module=rp.pl
+action=report
+report=ar_aging
+
+
+[General Ledger--Reports--AP Aging]
+ACCESS=general_ledger
+module=rp.pl
+action=report
+report=ap_aging
+
+[General Ledger--Reports--Journal]
+ACCESS=general_ledger
+module=gl.pl
+action=search
+
+
+[Cash]
+ACCESS=cash
+
+[Cash--Receipt]
+module=cp.pl
+action=payment
+type=receipt
+vc=customer
+
+[Cash--Payment]
+module=cp.pl
+action=payment
+type=check
+vc=vendor
+
+[Cash--Reconciliation]
+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
+action=acc_menu
+submenu=1
+
+[Cash--Reports--Receipts]
+module=rp.pl
+action=report
+report=receipts
+
+[Cash--Reports--Payments]
+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]
+
+[Reports--Chart of Accounts]
+ACCESS=report
+module=ca.pl
+action=chart_of_accounts
+
+[Reports--Trial Balance]
+ACCESS=report
+module=rp.pl
+action=report
+report=trial_balance
+
+[Reports--Income Statement]
+ACCESS=report
+module=rp.pl
+action=report
+report=income_statement
+
+[Reports--BWA]
+ACCESS=report
+module=rp.pl
+action=report
+report=bwa
+
+[Reports--Balance Sheet]
+ACCESS=report
+module=rp.pl
+action=report
+report=balance_sheet
+
+[Reports--UStVa]
+ACCESS=advance_turnover_tax_return
+module=ustva.pl
+action=report
+
+[Reports--Projecttransactions]
+ACCESS=report
+module=rp.pl
+action=report
+report=projects
+
+
+[Batch Printing]
+ACCESS=batch_printing
+
+[Batch Printing--Sales Invoices]
+ACCESS=invoice_edit
+module=bp.pl
+action=search
+vc=customer
+type=invoice
+
+[Batch Printing--Sales Orders]
+ACCESS=sales_order_edit
+module=bp.pl
+action=search
+vc=customer
+type=sales_order
+
+[Batch Printing--Quotations]
+ACCESS=sales_quotation_edit
+module=bp.pl
+action=search
+vc=customer
+type=sales_quotation
+
+[Batch Printing--Packing Lists]
+ACCESS=invoice_edit | sales_order_edit
+module=bp.pl
+action=search
+vc=customer
+type=packing_list
+
+[Batch Printing--Purchase Orders]
+ACCESS=purchase_order_edit
+module=bp.pl
+action=search
+vc=vendor
+type=purchase_order
+
+[Batch Printing--RFQs]
+ACCESS=request_quotation_edit
+module=bp.pl
+action=search
+vc=vendor
+type=request_quotation
+
+[Batch Printing--Checks]
+ACCESS=cash
+module=bp.pl
+action=search
+vc=vendor
+type=check
+
+[Batch Printing--Receipts]
+ACCESS=cash
+module=bp.pl
+action=search
+vc=customer
+type=receipt
+
+
+[Productivity]
+ACCESS=productivity
+
+[Productivity--Show TODO list]
+module=todo.pl
+action=show_todo_list
+
+[Productivity--Add Follow-Up]
+module=fu.pl
+action=add
+
+[Productivity--Edit Access Rights]
+module=fu.pl
+action=edit_access_rights
+
+[Productivity--Reports]
+module=menu.pl
+action=acc_menu
+submenu=1
+
+[Productivity--Reports--Follow-Ups]
+module=fu.pl
+action=search
+
+
+[System]
+ACCESS=config
+
+[System--Client Configuration]
+ACCESS=admin
+module=controller.pl
+action=ClientConfig/edit
+
+[System--UStVa Einstellungen]
+module=ustva.pl
+action=config_step1
+
+[System--Edit Dunning]
+module=dn.pl
+action=edit_config
+
+[System--Chart of Accounts]
+module=menu.pl
+action=acc_menu
+submenu=1
+
+[System--Chart of Accounts--Add Account]
+module=am.pl
+action=add_account
+
+[System--Chart of Accounts--List Accounts]
+module=am.pl
+action=list_account
+
+[System--Buchungsgruppen]
+module=am.pl
+action=list_buchungsgruppe
+
+[System--Taxes]
+module=am.pl
+action=list_tax
+
+[System--Bank accounts]
+module=bankaccounts.pl
+action=bank_account_list
+
+[System--Groups]
+module=pe.pl
+action=search
+type=partsgroup
+
+[System--Pricegroups]
+module=pe.pl
+action=search
+type=pricegroup
+
+[System--Edit units]
+module=am.pl
+action=edit_units
+
+[System--Price Factors]
+module=am.pl
+action=list_price_factors
+
+[System--Departments]
+module=controller.pl
+action=Department/list
+
+[System--Types of Business]
+module=controller.pl
+action=Business/list
+
+[System--Leads]
+module=am.pl
+action=list_lead
+
+[System--Languages and translations]
+module=menu.pl
+action=acc_menu
+submenu=1
+
+[System--Languages and translations--Add Language]
+module=am.pl
+action=add_language
+
+[System--Languages and translations--List Languages]
+module=am.pl
+action=list_language
+
+[System--Languages and translations--Greetings]
+module=generictranslations.pl
+action=edit_greetings
+
+[System--Languages and translations--SEPA strings]
+module=generictranslations.pl
+action=edit_sepa_strings
+
+
+[System--Payment Terms]
+module=controller.pl
+action=PaymentTerm/list
+
+[System--Manage Custom Variables]
+module=controller.pl
+action=CustomVariableConfig/list
+
+[System--Warehouses]
+module=am.pl
+action=list_warehouses
+
+
+[System--Import CSV]
+module=menu.pl
+action=acc_menu
+submenu=1
+
+[System--Import CSV--Customers and vendors]
+module=controller.pl
+action=CsvImport/new
+profile.type=customers_vendors
+
+[System--Import CSV--Contacts]
+module=controller.pl
+action=CsvImport/new
+profile.type=contacts
+
+[System--Import CSV--Shipto]
+module=controller.pl
+action=CsvImport/new
+profile.type=addresses
+
+[System--Import CSV--Parts]
+module=controller.pl
+action=CsvImport/new
+profile.type=parts
+
+[System--Import CSV--Projects]
+module=controller.pl
+action=CsvImport/new
+profile.type=projects
+
+[System--Templates]
+ACCESS=admin
+module=menu.pl
+action=acc_menu
+submenu=1
+
+[System--Templates--HTML Templates]
+module=amtemplates.pl
+action=display_template_form
+type=templates
+format=html
+
+[System--Templates--LaTeX Templates]
+module=amtemplates.pl
+action=display_template_form
+type=templates
+format=tex
+
+[System--Templates--Stylesheet]
+module=amtemplates.pl
+action=display_template_form
+type=stylesheet
+
+[System--General Ledger Corrections]
+module=acctranscorrections.pl
+action=analyze_filter
+
+[System--Background jobs and task server]
+ACCESS=admin
+module=menu.pl
+action=acc_menu
+submenu=1
+
+[System--Background jobs and task server--List current background jobs]
+module=controller.pl
+action=BackgroundJob/list
+
+[System--Background jobs and task server--Background job history]
+module=controller.pl
+action=BackgroundJobHistory/list
+
+[System--Background jobs and task server--Task server control]
+module=controller.pl
+action=TaskServer/show
+
+[System--Audit Control]
+module=am.pl
+action=audit_control
+
+[System--History Search Engine]
+module=am.pl
+action=show_history_search
+
+[System--Employees]
+ACCESS=admin
+module=controller.pl
+action=Employee/list
+
+[Program]
+
+[Program--User Preferences]
+module=am.pl
+action=config
+
+[Program--Version]
+module=login.pl
+action=company_logo
+no_todo_list=1
+
+[Program--Administration area]
+ACCESS=display_admin_link
+module=controller.pl
+action=Admin/login
+
+[Program--Documentation (in German)]
+href=doc/kivitendo-Dokumentation.pdf
+target=_blank
+
+[Program--kivitendo website (external)]
+href=http://www.kivitendo.de/
+target=_blank
+
+[Program--Logout]
+module=controller.pl
+action=LoginScreen/logout
index 3ae38a3..ed08548 100755 (executable)
@@ -18,7 +18,6 @@ use FileHandle;
 use Getopt::Long;
 use IO::Dir;
 use List::Util qw(first);
-use POSIX;
 use Pod::Usage;
 
 $OUTPUT_AUTOFLUSH = 1;
@@ -35,7 +34,7 @@ my $basedir      = "../..";
 my $locales_dir  = ".";
 my $bindir       = "$basedir/bin/mozilla";
 my @progdirs     = ( "$basedir/SL" );
-my $menufile     = "menu.ini";
+my @menufiles    = <${basedir}/menus/*.ini>;
 my @javascript_dirs = ($basedir .'/js', $basedir .'/templates/webpages');
 my $javascript_output_dir = $basedir .'/js';
 my $submitsearch = qr/type\s*=\s*[\"\']?submit/i;
@@ -89,15 +88,13 @@ my @customfiles  = grep /_custom/, @bindir_files;
 push @progfiles, map { m:^(.+)/([^/]+)$:; [ $2, $1 ] } grep { /\.pm$/ } map { find_files($_) } @progdirs;
 
 # put customized files into @customfiles
-my (@menufiles, %dir_h);
+my %dir_h;
 
 if ($opt_n) {
   @customfiles = ();
-  @menufiles   = ($menufile);
 } else {
   tie %dir_h, 'IO::Dir', $basedir;
-  @menufiles = map { "$basedir/$_" } grep { /.*?_$menufile$/ } keys %dir_h;
-  unshift @menufiles, "$basedir/$menufile";
+  push @menufiles, map { "$basedir/$_" } grep { /.*_menu.ini$/ } keys %dir_h;
 }
 
 my @dbplfiles;
@@ -724,11 +721,6 @@ sub generate_file {
   close $fh;
 }
 
-sub slurp {
-  my $file = shift;
-  do { local ( @ARGV, $/ ) = $file; <> }
-}
-
 __END__
 
 =head1 NAME
index ce8618f..b16ef2a 100644 (file)
@@ -12,12 +12,10 @@ sub run {
   my ($self) = @_;
 
   # 1. Ãœberprüfen ob Kontenrahmen SKR04 ist, wenn nicht alles Ã¼berspringen
-  my ($kontenrahmen) = $self->dbh->selectrow_array("select coa from defaults");
-
-  unless ( $kontenrahmen eq 'Germany-DATEV-SKR04EU' ) {
-    print "Kontenrahmen ist nicht SKR04, &uuml;berspringen<br>";
+  if (!$self->check_coa('Germany-DATEV-SKR04EU')) {
+    print qq|Nichts zu tun in diesem Kontenrahmen.|;
     return 1;
-  };
+  }
 
   # Mandant hat SKR04, erst prüfen wir, ob in der Vergangenheit Buchungen mit
   # taxkey 13 erfolgt sind (Fall "EU ohne USt. ID), diese sind wahrscheinlich
index 8b999f0..2f90d57 100644 (file)
@@ -4,8 +4,6 @@
 
 <h1>[% HTML.escape(title) %]</h1>
 
-<p><a href="controller.pl?action=Admin/database_administration">[% LxERP.t8('Back') %]</a></p>
-
 <form method="post" action="controller.pl">
  <p>
   [% LxERP.t8('You can either create a new database or chose an existing database.') %]
index dc0a214..ab92eb5 100644 (file)
@@ -2,37 +2,35 @@
 
 [% INCLUDE 'common/flash.html' %]
 
-<h1>[% HTML.escape(title) %]</h1>
+<h1>[% LxERP.t8("Database login (#1)", title) %]</h1>
 
-<p><a href="controller.pl?action=Admin/show">[% LxERP.t8('Back') %]</a></p>
+<p>[% LxERP.t8('Here you only provide the credentials for logging into the database.') %] [% LxERP.t8('Nothing will be created or deleted at this stage!') %]</p>
 
 <form method="post" action="controller.pl">
  <table>
   <tr>
    <th align="right">[% LxERP.t8('Host') %]</th>
-   <td>[% L.input_tag('dbhost', FORM.dbhost, size=30, class="initial_focus") %]</td>
+   <td>[% L.input_tag('dbhost', dbhost, size=30, class="initial_focus") %]</td>
    <th align="right">[% LxERP.t8('Port') %]</th>
-   <td>[% L.input_tag('dbport', FORM.dbport, size=6) %]</td>
+   <td>[% L.input_tag('dbport', dbport, size=6) %]</td>
   </tr>
 
   <tr>
    <th align="right">[% LxERP.t8('Database User') %]</th>
-   <td>[% L.input_tag("dbuser", FORM.dbuser, size=30) %]</td>
+   <td>[% L.input_tag("dbuser", dbuser, size=30) %]</td>
    <th align="right">[% LxERP.t8('Password') %]</th>
-   <td>[% L.input_tag("dbpasswd", FORM.dbpasswd, type='password', size=30) %]</td>
+   <td>[% L.input_tag("dbpasswd", dbpasswd, type='password', size=30) %]</td>
   </tr>
 
   <tr>
    <th align="right">[% LxERP.t8('Database template') %]</th>
-   <td>[% L.input_tag("dbdefault", FORM.dbdefault, size=30) %]</td>
+   <td>[% L.input_tag("dbdefault", dbdefault, size=30) %]</td>
   </tr>
  </table>
 
- <div>
-  [% L.hidden_tag("action", 'Admin/dispatch') %]
-  [% L.submit_tag('action_create_dataset', LxERP.t8('Create Dataset')) %]
-  [% L.submit_tag('action_delete_dataset', LxERP.t8('Delete Dataset')) %]
- </div>
-</form>
+ [% L.hidden_tag("action", 'Admin/dispatch') %]
 
-<p>[% LxERP.t8('This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!') %]</p>
+ <p>
+  [% L.submit_tag('action_' _ next_action, LxERP.t8('Login')) %]
+ </p>
+</form>
index e3b6115..dcc3b9e 100644 (file)
@@ -4,8 +4,6 @@
 
 <h1>[% HTML.escape(title) %]</h1>
 
-<p><a href="controller.pl?action=Admin/database_administration">[% LxERP.t8('Back') %]</a></p>
-
 <p>
  [% LxERP.t8('You can only delete datasets that are not in use.') %]
  [% LxERP.t8('If you want to delete such a dataset you have to edit the client(s) that are using the dataset in question and have them use another dataset.') %]
index dc5ca45..cd9983f 100644 (file)
@@ -5,8 +5,6 @@
 
 <h1>[% HTML.escape(title) %]</h1>
 
-<p>[% L.link(SELF.url_for(action="show"), LxERP.t8("Back")) %]</p>
-
 <form method="post" action="controller.pl" id="form">
  [% L.hidden_tag("client.id", SELF.client.id) %]
  [% L.hidden_tag("action", "") %]
index f9247f5..d471e5a 100644 (file)
@@ -5,8 +5,6 @@
 
 <h1>[% HTML.escape(title) %]</h1>
 
-<p>[% L.link(SELF.url_for(action="show"), LxERP.t8("Back")) %]</p>
-
 <form method="post" action="controller.pl" id="form">
  [% L.hidden_tag("group.id", SELF.group.id) %]
  [% L.hidden_tag("action", "") %]
index 7064416..8553c53 100644 (file)
@@ -2,14 +2,26 @@
 
 [% INCLUDE 'common/flash.html' %]
 
+[% IF !SELF.all_clients.size %]
+<div class="error">
+ [% LxERP.t8("Error") %]:
+ [% LxERP.t8("No clients have been created yet.") %]
+</div>
+
+[%- ELSE %]
+
 <h1>[% HTML.escape(title) %]</h1>
 
 <form method="post">
- [% L.hidden_tag("client.id", SELF.client.id) %]
  [% L.hidden_tag("action", 'Admin/dispatch') %]
  [% L.hidden_tag("printer.id", SELF.printer.id) %]
 
  <table>
+  <tr>
+   <th align="right">[% LxERP.t8('Client') %]</th>
+   <td>[% L.select_tag("client.id", SELF.all_clients, default=SELF.client.id, title_key='name') %]</td>
+  <tr>
+
   <tr>
    <th align="right">[% LxERP.t8('Printer Description') %]</th>
    <td>[% L.input_tag("printer.printer_description", SELF.printer.printer_description, size=30, class="initial_focus") %]</td>
@@ -33,3 +45,5 @@
  </p>
 
 </form>
+
+[% END %]
index b8b5dc4..ff6a188 100644 (file)
@@ -5,8 +5,6 @@
 
 <h1>[% HTML.escape(title) %]</h1>
 
-<p>[% L.link(SELF.url_for(action="show"), LxERP.t8("Back")) %]</p>
-
 <form method="post" action="controller.pl" id="form">
  [% L.hidden_tag("user.id", SELF.user.id) %]
  [% L.hidden_tag("action", "") %]
index 4da7eff..a91fa75 100644 (file)
  [% LxERP.t8("No clients have been created yet.") %]
 </div>
 
-<div>
- <a href="[% SELF.url_for(action='show') %]">[% LxERP.t8("Back") %]</a>
-</div>
-
 [%- ELSE %]
 
- <div>
-  [% LxERP.t8("Actions") %]:
-  <span class="link_separator"></span>
-  <a href="[% SELF.url_for(action='show') %]">[% LxERP.t8("Back") %]</a>
-  <span class="link_separator">|</span>
-  <a href="[% SELF.url_for(action='new_printer', 'client.id'=SELF.client.id) %]">[% LxERP.t8("Add printer") %]</a>
- </div>
-
- <hr>
-
  <p>
   [% LxERP.t8("Client to configure the printers for") %]:
   [% L.select_tag('client.id', SELF.all_clients, id='client_id', title_key='name', default=SELF.client.id) %]
index f8bd272..7189665 100644 (file)
@@ -4,32 +4,6 @@
 
 <h1>[% HTML.escape(title) %]</h1>
 
-<div>
- [% LxERP.t8("Actions") %]:
- <span class="link_separator"></span>
- [% L.link(SELF.url_for(action="new_user"), LxERP.t8("Add User")) %]
- <span class="link_separator">|</span>
- [% L.link(SELF.url_for(action="new_client"), LxERP.t8("Add Client")) %]
- <span class="link_separator">|</span>
- [% L.link(SELF.url_for(action="new_group"), LxERP.t8("Add User Group")) %]
- <span class="link_separator">|</span>
- [% L.link(SELF.url_for(action="database_administration"), LxERP.t8("Pg Database Administration")) %]
- <span class="link_separator">|</span>
- [% L.link(SELF.url_for(action="list_printers"), LxERP.t8("Printer Management")) %]
- <span class="link_separator">|</span>
- [% IF SELF.is_locked %]
-  [% L.link(SELF.url_for(action="unlock_system"), LxERP.t8("Unlock System")) %]
- [% ELSE %]
-  [% L.link(SELF.url_for(action="lock_system"), LxERP.t8("Lock System")) %]
- [% END %]
- <span class="link_separator">|</span>
- [% L.link(SELF.url_for(action="logout"), LxERP.t8("Logout")) %]
- <span class="link_separator">|</span>
- [% L.link(SELF.url_for(controller="LoginScreen", action="user_login"), LxERP.t8("To user login")) %]
-</div>
-
-<hr>
-
 <div class="tabwidget">
  <ul>
   <li><a href="#user_list">[%- LxERP.t8("User list") %]</a></li>
diff --git a/templates/webpages/admin/show_lock.html b/templates/webpages/admin/show_lock.html
new file mode 100644 (file)
index 0000000..f9a9cdd
--- /dev/null
@@ -0,0 +1,30 @@
+[%- USE HTML %][%- USE LxERP -%][%- USE L -%]
+
+[% INCLUDE 'common/flash.html' %]
+
+<h1>[% HTML.escape(title) %]</h1>
+
+[% IF SELF.is_locked %]
+<p>
+ [% LxERP.t8("The installation is currently locked.") %]
+ [% LxERP.t8("Normal users cannot log in.") %]
+ [% LxERP.t8("The administration area is always accessible.") %]
+</p>
+
+<p><a href="[% SELF.url_for(action='unlock_system') %]">[% LxERP.t8("Unlock System") %]</a></p>
+
+[% ELSE %]
+
+<p>
+ [% LxERP.t8("The installation is currently unlocked.") %]
+ [% LxERP.t8("Everyone can log in.") %]
+</p>
+
+<p>
+ [% LxERP.t8("If you lock the system normal users won't be able to log in.") %]
+ [% LxERP.t8("The administration area is always accessible.") %]
+</p>
+
+<p><a href="[% SELF.url_for(action='lock_system') %]">[% LxERP.t8("Lock System") %]</a></p>
+
+[% END %]
diff --git a/templates/webpages/ct/ajax_autocomplete2.json b/templates/webpages/ct/ajax_autocomplete2.json
deleted file mode 100644 (file)
index f4a44e3..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-[%- USE HTML %][% USE JSON %][
-[%- FOREACH customer = SELF.customers %]
- {
-   "value": [% customer.${SELF.value}.json %],
-   "label": [% customer.displayable_name.json %],
-   "id": [% customer.id.json %],
-   "customernumber": [% customer.customernumber.json %],
-   "name": [% customer.name.json %]
-  }[% ',' UNLESS loop.last %]
-[%- END %]
-]
diff --git a/templates/webpages/customer_vendor/form.html b/templates/webpages/customer_vendor/form.html
new file mode 100644 (file)
index 0000000..c8ec6b0
--- /dev/null
@@ -0,0 +1,105 @@
+[%- USE T8 %]
+[%- USE LxERP %]
+[%- USE L %]
+
+[% cv_cvars = SELF.cv.cvars_by_config %]
+
+<form method="post" action="controller.pl">
+  <div class="listtop">[% FORM.title %]</div>
+
+  [% L.hidden_tag('db', FORM.db) %]
+  [% L.hidden_tag('callback', FORM.callback) %]
+  [% L.hidden_tag('cv.id', SELF.cv.id) %]
+
+  [%- INCLUDE 'common/flash.html' %]
+
+  <div class="tabwidget" id="customer_vendor_tabs">
+    <ul>
+      <li><a href="#billing">[% 'Billing Address' | $T8 %]</a></li>
+      <li><a href="#shipto">[% 'Shipping Address' | $T8 %]</a></li>
+      <li><a href="#contacts">[% 'Contacts' | $T8 %]</a></li>
+      [% IF ( SELF.cv.id ) %]
+        <li><a href="#deliveries">[% 'Supplies' | $T8 %]</a></li>
+      [% END %]
+      <li><a href="#vcnotes">[% 'Notes' | $T8 %]</a></li>
+
+      [% IF ( cv_cvars.size ) %]
+        <li><a href="#custom_variables">[% 'Custom Variables' | $T8 %]</a></li>
+      [% END %]
+    </ul>
+
+    [% PROCESS "customer_vendor/tabs/billing.html" %]
+    [% PROCESS "customer_vendor/tabs/shipto.html" %]
+    [% PROCESS "customer_vendor/tabs/contacts.html" %]
+    [% IF ( SELF.cv.id ) %]
+      [% PROCESS "customer_vendor/tabs/deliveries.html" %]
+    [% END %]
+    [% PROCESS "customer_vendor/tabs/vcnotes.html" %]
+    [% IF ( cv_cvars.size ) %]
+      [% PROCESS "customer_vendor/tabs/custom_variables.html" %]
+    [% END %]
+  </div>
+
+  <br>
+
+  [% L.hidden_tag('action', 'CustomerVendor/dispatch') %]
+
+  [% L.submit_tag('action_save', LxERP.t8('Save'), onclick = "return check_taxzone_and_ustid()", accesskey = "s") %]
+  [% L.submit_tag('action_save_and_close', LxERP.t8('Save and Close'), onclick = "return check_taxzone_and_ustid()") %]
+
+  [%- IF ( SELF.is_vendor ) %]
+    [% L.submit_tag('action_save_and_ap_transaction', LxERP.t8('Save and AP Transaction'), onclick = "return check_taxzone_and_ustid()") %]
+  [%- ELSE %]
+    [% L.submit_tag('action_save_and_ar_transaction', LxERP.t8('Save and AR Transaction'), onclick = "return check_taxzone_and_ustid()") %]
+  [%- END %]
+
+  [% L.submit_tag('action_save_and_invoice', LxERP.t8('Save and Invoice'), onclick = "return check_taxzone_and_ustid()") %]
+  [% L.submit_tag('action_save_and_order', LxERP.t8('Save and Order'), onclick = "return check_taxzone_and_ustid()") %]
+
+  [%- IF ( SELF.is_vendor ) %]
+    [% L.submit_tag('action_save_and_rfq', LxERP.t8('Save and RFQ'), onclick = "return check_taxzone_and_ustid()") %]
+  [%- ELSE %]
+    [% L.submit_tag('action_save_and_quotation', LxERP.t8('Save and Quotation'), onclick = "return check_taxzone_and_ustid()") %]
+  [%- END %]
+
+  [%- IF ( SELF.cv.id && SELF.is_orphaned ) %]
+    [% L.submit_tag('action_delete', LxERP.t8('Delete'), confirm => LxERP.t8('Do you really want to delete this object?')) %]
+  [%- END %]
+
+  [%- IF ( SELF.cv.id ) %]
+    <input type="button" class="submit" onclick="kivi.CustomerVendor.showHistoryWindow([% SELF.cv.id %]);" name="history" id="history" value="[% 'history' | $T8 %]">
+  [%- END %]
+
+</form>
+
+<script type="text/javascript">
+<!--
+  function submitInputButton(button)
+  {
+    var hidden = document.createElement("input");
+    hidden.setAttribute("type", "hidden");
+
+    if ( button.hasAttribute("name") )
+      hidden.setAttribute("name", button.getAttribute("name"));
+
+    if ( button.hasAttribute("value") )
+      hidden.setAttribute("value", button.getAttribute("value"));
+
+
+    button.form.appendChild(hidden);
+
+    button.disabled = true;
+
+    button.form.submit();
+  }
+
+  function check_taxzone_and_ustid() {
+    if ( ($('#cv_taxzone_id').val() == '1') && ($('#cv_ustid').val() == '') ) {
+      alert('[% LxERP.t8('Please enter the sales tax identification number.') %]');
+      return false;
+    }
+    return true;
+  }
+-->
+</script>
+
diff --git a/templates/webpages/customer_vendor/get_delivery.html b/templates/webpages/customer_vendor/get_delivery.html
new file mode 100644 (file)
index 0000000..7cfc76f
--- /dev/null
@@ -0,0 +1,48 @@
+[% USE T8 %]
+[% USE HTML %]
+[% USE LxERP %]
+<div id="delivery">
+  <table width="100%">
+    <tr>
+      <td>
+        <table width="100%">
+          <tr class="listheading">
+            <th class="listheading">[% 'Shipping Address' | $T8 %]</th>
+            <th class="listheading">[% 'Invoice' | $T8 %]</th>
+            <th class="listheading">[% 'Order' | $T8 %]</th>
+            <th class="listheading">[% 'Invdate' | $T8 %]</th>
+            <th class="listheading">[% 'Description' | $T8 %]</th>
+            <th class="listheading">[% 'Qty' | $T8 %]</th>
+            <th class="listheading">[% 'Unit' | $T8 %]</th>
+            [% IF ( SELF.is_customer() ) %]
+              <th class="listheading">[% 'Sell Price' | $T8 %]</th>
+            [% ELSE %]
+              <th class="listheading">[% 'Last Cost' | $T8 %]</th>
+            [%- END %]
+          </tr>
+
+
+          [% FOREACH row = SELF.delivery %]
+            [% row.script = SELF.is_vendor() ? ( row.invoice ? 'ir' : 'ap' ) : ( row.invoice ? 'is' : 'ar' ) %]
+            <tr class="listrow[% loop.count % 2 %]">
+              <td>[% HTML.escape(row.shiptoname) UNLESS loop.prev.shiptoname == row.shiptoname %]&nbsp;</td>
+              <td>[% IF row.id %]<a href='[% row.script %].pl?action=edit&id=[% HTML.escape(row.id) %]'>[% END %][% HTML.escape(row.invnumber)   || '&nbsp;' %][% IF row.id %]</a>[% END %]</td>
+              <td>[% IF row.oe_id %]<a href='oe.pl?action=edit&type=[% IF is_customer %]sales_order[% ELSE %]purchase_order[% END %]&vc=customer&id=[% HTML.escape(row.oe_id) %]'>[% END %][% HTML.escape(row.ordnumber)   || '&nbsp;' %][% IF row.oe_id %]</a>[% END %]</td>
+              <td>[% HTML.escape(row.transdate)   || '&nbsp;' %]</td>
+              <td>[% HTML.escape(row.description) || '&nbsp;' %]</td>
+              <td>[% HTML.escape(row.qty)         || '&nbsp;' %]</td>
+              <td>[% HTML.escape(row.unit)        || '&nbsp;' %]</td>
+              <td>[% LxERP.format_amount(row.sellprice, 2) || '&nbsp;' %]</td>
+            </tr>
+          [% END %]
+
+        </table>
+
+        [% IF DELIVERY.size == 15 %]
+          <p>[% 'This list is capped at 15 items to keep it fast. If you need a full list, please use reports.' | $T8 %]</p>
+        [% END %]
+
+      </td>
+    </tr>
+  </table>
+</div>
diff --git a/templates/webpages/customer_vendor/render_cvar_input.html b/templates/webpages/customer_vendor/render_cvar_input.html
new file mode 100644 (file)
index 0000000..c1b7720
--- /dev/null
@@ -0,0 +1,34 @@
+[%- USE T8 %]
+[%- USE HTML %]
+[%- USE L %]
+[%- USE LxERP %]
+
+[%- SET var_name = HTML.escape(cvar_name_prefix) _ HTML.escape(var.config.name) _ HTML.escape(cvar_name_postfix) %]
+
+[%- IF ( hide_non_editable && !var.config.is_flag('editable') ) %]
+  [% L.hidden_tag(var_name, var.value) %]
+[%- ELSIF ( !var.is_valid ) %]
+  [%- IF ( show_disabled_message ) %]
+    [% 'Element disabled' | $T8 %]
+  [%- END %]
+[%- ELSIF ( var.config .type == 'bool' ) %]
+  [% L.checkbox_tag(var_name, checked = var.value) %]
+[%- ELSIF ( var.config .type == 'textfield' ) %]
+  [% L.textarea_tag(var_name, var.value, cols = var.config.processed_options.WIDTH, rows = var.config.processed_options.HEIGHT) %]
+[%- ELSIF ( var.config.type == 'date' ) %]
+  [% L.date_tag(var_name, var.value) %]
+[%- ELSIF ( var.config.type == 'timestamp' ) %]
+  [% L.input_tag(var_name, var.value) %]
+[%- ELSIF ( var.config.type == 'customer' ) %]
+  [% L.customer_picker(var_name, var.value) %]
+[%- ELSIF ( var.config.type == 'vendor' ) %]
+  [% L.vendor_selector(var_name, var.value) %]
+[%- ELSIF ( var.config.type == 'part' ) %]
+  [% L.part_selector(var_name, var.value) %]
+[%- ELSIF ( var.config.type == 'select' ) %]
+  [% L.select_tag(var_name, var.config.processed_options, default = var.value) %]
+[%- ELSIF ( var.config.type == 'number' ) %]
+  [%- L.input_tag(var_name, LxERP.format_amount(var.value, -2)) %]
+[%- ELSE %]
+  [% L.input_tag(var_name, var.value, maxlength = var.config.processed_options.MAXLENGTH) %]
+[%- END %]
diff --git a/templates/webpages/customer_vendor/tabs/billing.html b/templates/webpages/customer_vendor/tabs/billing.html
new file mode 100644 (file)
index 0000000..b7dfe9e
--- /dev/null
@@ -0,0 +1,380 @@
+[%- USE T8 %]
+[%- USE HTML %]
+[%- USE LxERP %]
+[%- USE L %]
+
+<div id="billing">
+  <table width="100%">
+
+    <tr height="5"></tr>
+
+    [% IF ( conf_vertreter ) %]
+      <tr>
+        <th align="right">
+          [% IF SELF.is_vendor() %]
+            [% 'Type of Vendor' | $T8 %]
+          [% ELSE %]
+            [% 'Type of Customer' | $T8 %]
+          [% END %]
+        </th>
+
+        <td>
+          [% L.select_tag('cv.business_id', SELF.all_business, value_key = 'id', title_key = 'description', default = SELF.cv.business_id, with_empty = 1) %]
+        </td>
+      </tr>
+
+      <tr>
+        <th align="right">
+          [% 'Representative' | $T8 %]
+        </th>
+
+        <td>
+          [% L.select_tag('cv.salesman_id', SELF.all_salesman_customers, default = SELF.cv.salesman_id, value_key = 'id', title_key = 'name', with_empty = 1) %]
+        </td>
+      </tr>
+
+    [%- END %]
+
+    <tr>
+      [% IF SELF.is_vendor() %]
+        <th align="right" nowrap>[% 'Vendor Number' | $T8 %]</th>
+        <td>
+          [% L.input_tag('cv.vendornumber', SELF.cv.vendornumber) %]
+        </td>
+      [%- ELSE %]
+        <th align="right" nowrap>[% 'Customer Number' | $T8 %]</th>
+        <td>
+          [% L.input_tag('cv.customernumber', SELF.cv.customernumber) %]
+        </td>
+      [%- END %]
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'Greeting' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('cv.greeting', SELF.cv.greeting) %]
+        [% L.select_tag('cv_greeting_select', SELF.all_greetings, default = SELF.cv.greeting, with_empty = 1, onchange = '$("#cv_greeting").val(this.value);') %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>
+        [% IF SELF.is_vendor() %]
+          [% 'Vendor Name' | $T8 %]
+        [%- ELSE %]
+          [% 'Customer Name' | $T8 %]
+        [%- END %]
+      </th>
+
+      <td>
+        [% L.input_tag('cv.name', SELF.cv.name) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'Department' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('cv.department_1', SELF.cv.department_1, size = 16, maxlength = 75) %]
+        [% L.input_tag('cv.department_2', SELF.cv.department_2, size = 16, maxlength = 75) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'Street' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('cv.street', SELF.cv.street, size = 35, maxlength = 75) %]
+        <span id="billing_map"></span>
+        <script type="text/javascript">
+          billingMapWidget = new kivi.CustomerVendor.MapWidget('cv_');
+          $(function() {
+            billingMapWidget.render($('#billing_map'));
+          });
+        </script>
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'Zipcode' | $T8 %]/[% 'City' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('cv.zipcode', SELF.cv.zipcode, size = 5 maxlength = 10) %]
+        [% L.input_tag('cv.city', SELF.cv.city, size = 30 maxlength = 75) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'Country' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('cv.country', SELF.cv.country, size = 30 maxlength = 75) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'Contact' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('cv.contact', SELF.cv.contact, size = 28 maxlength = 75) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'Phone' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('cv.phone', SELF.cv.phone, size = 30) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'Fax' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('cv.fax', SELF.cv.fax, size = 30 maxlength = 30) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'E-mail' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('cv.email', SELF.cv.email, size = 45) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right">[% 'Cc E-mail' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('cv.cc', SELF.cv.bcc, size = 45) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right">[% 'Bcc E-mail' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('cv.bcc', SELF.cv.bcc, size = 45) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>
+        [% IF homepage %]
+          <a href="[% HTML.escape(SELF.cv.homepage) %]" title="[% 'Open this Website' | $T8 %]" target="_blank">[% 'Homepage' | $T8 %]</a>
+        [% ELSE %]
+          [% 'Homepage' | $T8 %]
+        [% END %]
+      </th>
+
+      <td>
+        [% L.input_tag('cv.homepage', SELF.cv.homepage, size = 45, title = LxERP.t8('Example: http://kivitendo.de')) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'Username' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('cv.username', SELF.cv.username, size = 45) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'Password' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('cv.user_password', SELF.cv.user_password, size = 45) %]
+      </td>
+    </tr>
+  </table>
+
+
+  <table>
+
+    <tr>
+      <th align="right">[% 'Credit Limit' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('cv.creditlimit_as_number', SELF.cv.creditlimit_as_number, size = 9) %]
+      </td>
+
+
+      <th align="right">[% 'Payment Terms' | $T8 %]</th>
+
+      <td>
+        [% L.select_tag('cv.payment_id', SELF.all_payment_terms, value_key = 'id', title_key = 'description', default = SELF.cv.payment_id, with_empty = 1) %]
+      </td>
+
+
+      <th align="right">[% 'Discount' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('cv.discount_as_percent', SELF.cv.discount_as_percent, size = 4) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right">[% 'Tax Number / SSN' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('cv.taxnumber', SELF.cv.taxnumber, size = 20) %]
+      </td>
+
+
+      <!-- Anm.: R&B 15.11.2008     VAT Reg No ist Ust-ID in GB, aber generell sollte es laut Richardson die sales tax id sein -->
+      <th align="right">[% 'sales tax identification number' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('cv.ustid', SELF.cv.ustid, maxlength = 14 size = 20 ) %]
+      </td>
+
+
+      [%- IF ( SELF.is_vendor() ) %]
+        <th align="right">[% 'Customer Number' | $T8 %]</th>
+        <td>
+          [% L.input_tag('cv.v_customer_id', SELF.cv.v_customer_id, size = 10) %]
+        </td>
+      [%- ELSE %]
+        <th align="right">[% 'our vendor number at customer' | $T8 %]</th>
+        <td>
+          [% L.input_tag('cv.c_vendor_id', SELF.cv.c_vendor_id, size = 10) %]
+        </td>
+      [%- END %]
+    </tr>
+
+    <tr>
+      <th align="right">[% 'Account Number' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('cv.account_number', SELF.cv.account_number, size = 10, maxlength = 100) %]
+      </td>
+
+
+      <th align="right">[% 'Bank Code Number' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('cv.bank_code', SELF.cv.bank_code, size = 10, maxlength = 100) %]
+      </td>
+
+
+      <th align="right">[% 'Bank' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('cv.bank', SELF.cv.bank, size = 20) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right">[% 'IBAN' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('cv.iban', SELF.cv.iban, size = 10, maxlength = 100) %]
+      </td>
+
+
+      <th align="right">[% 'BIC' | $T8 %]</th>
+      <td>
+        [% L.input_tag('cv.bic', SELF.cv.bic, size = 10, maxlength = 100) %]
+      </td>
+
+
+      [% IF ( SELF.all_currencies.size ) %]
+        <th align="right">[% 'Currency' | $T8 %]</th>
+
+        <td>
+          [% L.select_tag('cv.currency_id', SELF.all_currencies, title_key = 'name', value_key = 'id', default = SELF.cv.currency_id, with_empty = 1) %]
+        </td>
+      [% END %]
+    </tr>
+
+    <tr>
+      [% IF ( !conf_vertreter ) %]
+        <th align="right">
+          [% IF ( SELF.is_vendor() ) %]
+            [% 'Type of Vendor' | $T8 %]
+          [% ELSE %]
+            [% 'Type of Customer' | $T8 %]
+          [% END %]
+        </th>
+
+        <td>
+          [% L.select_tag('cv.business_id', SELF.all_business, default = SELF.cv.business_id, value_key = 'id', title_key = 'description', with_empty = 1) %]
+        </td>
+      [% END %]
+
+
+      <th align="right">[% 'Language' | $T8 %]</th>
+
+      <td>
+        [% L.select_tag('cv.language_id', SELF.all_languages, default = SELF.cv.language_id, value_key = 'id', title_key = 'description', with_empty = 1) %]
+      </td>
+
+      [% IF ( SELF.is_customer() ) %]
+        <th align="right">[% 'Preisklasse' | $T8 %]</th>
+
+        <td>
+          [% L.select_tag('cv.klass', SELF.all_pricegroups, default = SELF.cv.klass, value_key = 'id', title_key = 'pricegroup', with_empty = 1) %]
+        </td>
+      [% END  %]
+    </tr>
+
+    <tr>
+      <td align="right">
+        <label for="cv_obsolete">[% 'Obsolete' | $T8 %]</label>
+      </td>
+
+      <td>
+        [% L.checkbox_tag('cv.obsolete', checked = SELF.cv.obsolete) %]
+      </td>
+
+
+      <td align="right">
+        <label for="cv_direct_debit">[% 'direct debit' | $T8 %]</label>
+      </td>
+
+      <td>
+        [% L.checkbox_tag('cv.direct_debit', checked = SELF.cv.direct_debit) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right">[% 'Steuersatz' | $T8 %]</th>
+
+      <td>
+        [% L.select_tag('cv.taxzone_id', SELF.all_taxzones, default = SELF.cv.taxzone_id, value_key = 'id', title_key = 'description') %]
+      </td>
+
+
+      [% IF ( SELF.is_customer() && !conf_vertreter ) %]
+        <th align="right">[% 'Salesman' | $T8 %]</th>
+
+        <td>
+          [% L.select_tag('cv.salesman_id', SELF.all_salesmen, default = SELF.cv.salesman_id, value_key = 'id', title_key = 'safe_name', with_empty = 1) %]
+        </td>
+      [%- END %]
+
+      <td>[% 'taxincluded checked' | $T8 %]</td>
+
+      <td>
+        [% L.select_tag('cv.taxincluded_checked', [[undef, LxERP.t8('use user config')], ['1', LxERP.t8('Yes')], ['0', LxERP.t8('No')]], default = SELF.cv.taxincluded_checked) %]
+      </td>
+
+    </tr>
+  </table>
+
+  <table>
+    <tr>
+      <th align="left" nowrap>[% 'Internal Notes' | $T8 %]</th>
+    </tr>
+
+    <tr>
+      <td>
+        [% L.textarea_tag('cv.notes', SELF.cv.notes, rows = 3 cols = 60 wrap = soft) %]
+      </td>
+    </tr>
+  </table>
+</div>
diff --git a/templates/webpages/customer_vendor/tabs/contacts.html b/templates/webpages/customer_vendor/tabs/contacts.html
new file mode 100644 (file)
index 0000000..6420cbe
--- /dev/null
@@ -0,0 +1,233 @@
+[%- USE T8 %]
+[%- USE HTML %]
+[%- USE LxERP %]
+[%- USE L %]
+
+<div id="contacts">
+  <table>
+    <tr>
+      <th align="left">[% 'Contacts' | $T8 %]</th>
+
+      <td>
+        [%
+          L.select_tag(
+            'contact.cp_id',
+            SELF.contacts,
+            default = SELF.contact.cp_id,
+            with_empty = 1,
+            empty_title = LxERP.t8('New contact'),
+            value_key = 'cp_id',
+            title_key = 'full_name',
+            onchange = "kivi.CustomerVendor.selectContact({onFormSet: function(){contactsMapWidget.testInputs();}});",
+          )
+        %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="left" nowrap>[% 'Gender' | $T8 %]</th>
+
+      <td>
+        [%
+          L.select_tag(
+            'contact.cp_gender',
+            [['m', LxERP.t8('male')], ['f', LxERP.t8('female')]],
+            default = SELF.contact.cp_gender
+          )
+        %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="left" nowrap>[% 'Title' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('contact.cp_title', SELF.contact.cp_title, size = 40 maxlength = 75) %]
+        [% L.select_tag('contact_cp_title_select', SELF.all_titles, with_empty = 1, onchange = '$("#contact_cp_title").val(this.value);') %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="left" nowrap>[% 'Department' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('contact.cp_abteilung', SELF.contact.cp_abteilung, size = 40) %]
+        [% L.select_tag('contact_cp_abteilung_select', SELF.all_departments, default = SELF.contact.cp_abteilung,  with_empty = 1, onchange = '$("#contact_cp_abteilung").val(this.value);') %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="left" nowrap>[% 'Function/position' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('contact.cp_position', SELF.contact.cp_position, size = 40, maxlength = 75) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="left" nowrap>[% 'Given Name' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('contact.cp_givenname', SELF.contact.cp_givenname, size = 40, maxlength = 75) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="left" nowrap>[% 'Name' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('contact.cp_name', SELF.contact.cp_name, size = 40, maxlength = 75) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="left" nowrap>[% 'E-mail' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('contact.cp_email', SELF.contact.cp_email, size = 40) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="left" nowrap>[% 'Phone1' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('contact.cp_phone1', SELF.contact.cp_phone1, size = 40, maxlength = 75) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="left" nowrap>[% 'Phone2' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('contact.cp_phone2', SELF.contact.cp_phone2, size = 40, maxlength = 75) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="left" nowrap>[% 'Fax' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('contact.cp_fax', SELF.contact.cp_fax, size = 40) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="left" nowrap>[% 'Mobile1' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('contact.cp_mobile1', SELF.contact.cp_mobile1, size = 40) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="left" nowrap>[% 'Mobile2' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('contact.cp_mobile2', SELF.contact.cp_mobile2, size = 40) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="left" nowrap>[% 'Sat. Phone' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('contact.cp_satphone', SELF.contact.cp_satphone, size = 40) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="left" nowrap>[% 'Sat. Fax' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('contact.cp_satfax', SELF.contact.cp_satfax, size = 40) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="left" nowrap>[% 'Project' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('contact.cp_project', SELF.contact.cp_project, size = 40) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="left" nowrap>[% 'Street' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('contact.cp_street', SELF.contact.cp_street, size = 40, maxlength = 75) %]
+        <span id="contact_map"></span>
+        <script type="text/javascript">
+          var contactsMapWidget = new kivi.CustomerVendor.MapWidget('contact_cp_');
+          $(function() {
+            contactsMapWidget.render($('#contact_map'));
+          });
+        </script>
+      </td>
+    </tr>
+
+    <tr>
+      <th align="left" nowrap>[% 'Zip, City' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('contact.cp_zipcode', SELF.contact.cp_zipcode, size = 5, maxlength = 10) %]
+        [% L.input_tag('contact.cp_city', SELF.contact.cp_city, size = 25, maxlength = 75) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="left" nowrap>[% 'Private Phone' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('contact.cp_privatphone', SELF.contact.cp_privatphone, size = 40) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="left" nowrap>[% 'Private E-mail' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('contact.cp_privatemail', SELF.contact.cp_privatemail, size = 40) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="left" nowrap>[% 'Birthday' | $T8 %]</th>
+
+      <td>
+        [% L.date_tag('contact.cp_birthday', SELF.contact.cp_birthday) %]
+      </td>
+    </tr>
+
+    [% contact_cvars = SELF.contact.cvars_by_config %]
+
+    [% IF ( contact_cvars.size ) %]
+      <tr>
+        <td colspan="2">
+          <hr>
+        </td>
+      </tr>
+
+      [% FOREACH var = contact_cvars %]
+        <tr>
+          <th align="left" valign="top" nowrap>[% var.config.description | html %]</th>
+
+          <td valign="top">
+            [% PROCESS 'customer_vendor/render_cvar_input.html'
+                       cvar_name_prefix = 'contact_cvars.'
+            %]
+          </td>
+        </tr>
+      [% END %]
+    [% END %]
+
+  </table>
+
+  [% L.button_tag('submitInputButton(this);', LxERP.t8('Delete Contact'), name = 'action_delete_contact', class = 'submit') %]
+  [% IF ( !SELF.contact.cp_id ) %]
+    <script type="text/javascript">
+      $('#action_delete_contact').hide();
+    </script>
+  [% END %]
+</div>
diff --git a/templates/webpages/customer_vendor/tabs/custom_variables.html b/templates/webpages/customer_vendor/tabs/custom_variables.html
new file mode 100644 (file)
index 0000000..a0a90f9
--- /dev/null
@@ -0,0 +1,19 @@
+[%- USE HTML %]
+
+<div id="custom_variables">
+  <p>
+    <table>
+      [% FOREACH var = cv_cvars %]
+        <tr>
+          <th align="left" valign="top" nowrap>[% var.config.description | html %]</th>
+
+          <td valign="top">
+            [% PROCESS 'customer_vendor/render_cvar_input.html'
+                        cvar_name_prefix = 'cv_cvars.'
+            %]
+          </td>
+        </tr>
+      [% END %]
+    </table>
+  </p>
+</div>
diff --git a/templates/webpages/customer_vendor/tabs/deliveries.html b/templates/webpages/customer_vendor/tabs/deliveries.html
new file mode 100644 (file)
index 0000000..8cf755f
--- /dev/null
@@ -0,0 +1,58 @@
+[%- USE T8 %]
+[%- USE LxERP %]
+[%- USE L %]
+
+<div id="deliveries">
+  <table>
+    <tr>
+      <th align="right">[% 'Shipping Address' | $T8 %]</th>
+      <td colspan="3">
+        [% temp = [{shipto_id = 'all', displayable_id = LxERP.t8('All')}] %]
+        [% temp = temp.merge(SELF.shiptos) %]
+        [%
+          L.select_tag(
+            'delivery_id',
+            temp,
+            value_key = 'shipto_id',
+            title_key = 'displayable_id',
+            with_empty = 1,
+            onchange = "kivi.CustomerVendor.selectDelivery();"
+          )
+        %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'From' | $T8 %]</th>
+
+      <td>
+        [%
+          L.date_tag(
+            'delivery_from',
+            FORM.delivery_from,
+            onchange => "kivi.CustomerVendor.selectDelivery(this.form.delivery_from.value, this.form.delivery_to.value);"
+          )
+        %]
+      </td>
+
+
+      <th align="right" nowrap>[% 'To (time)' | $T8 %]</th>
+
+      <td>
+        [%
+          L.date_tag(
+            'delivery_to',
+            FORM.delivery_to,
+            onchange => "kivi.CustomerVendor.selectDelivery(this.form.delivery_from.value, this.form.delivery_to.value);"
+          )
+        %]
+      </td>
+    </tr>
+
+    <tr>
+      <td colspan="4">
+        <div id="delivery"></div>
+      </td>
+    </tr>
+  </table>
+</div>
diff --git a/templates/webpages/customer_vendor/tabs/shipto.html b/templates/webpages/customer_vendor/tabs/shipto.html
new file mode 100644 (file)
index 0000000..0b238c3
--- /dev/null
@@ -0,0 +1,114 @@
+[%- USE T8 %]
+[%- USE LxERP %]
+[%- USE L %]
+
+<div id="shipto">
+  <table width="100%" id="shipto_table">
+    <tr>
+      <th align="right">[% 'Shipping Address' | $T8 %]</th>
+
+      <td>
+        [% L.select_tag(
+             'shipto.shipto_id',
+             SELF.shiptos,
+             default = SELF.shipto.shipto_id,
+             value_key = 'shipto_id',
+             title_key = 'displayable_id',
+             with_empty = 1,
+             empty_title = LxERP.t8('New shipto'),
+             onchange = "kivi.CustomerVendor.selectShipto({onFormSet: function(){shiptoMapWidget.testInputs();}});",
+           )
+        %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'Name' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('shipto.shiptoname', SELF.shipto.shiptoname,  size = 35, maxlength = 75) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'Abteilung' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('shipto.shiptodepartment_1', SELF.shipto.shiptodepartment_1,  size = 16, maxlength = 75) %]
+        [% L.input_tag('shipto.shiptodepartment_2', SELF.shipto.shiptodepartment_2,  size = 16, maxlength = 75) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'Street' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('shipto.shiptostreet', SELF.shipto.shiptostreet,  size = 35, maxlength = 75) %]
+
+        <span id="shipto_map"></span>
+        <script type="text/javascript">
+          shiptoMapWidget = new kivi.CustomerVendor.MapWidget('shipto_shipto');
+          $(function() {
+            shiptoMapWidget.render($('#shipto_map'));
+          });
+        </script>
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'Zipcode' | $T8 %]/[% 'City' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('shipto.shiptozipcode', SELF.shipto.shiptostreet,  size = 5, maxlength = 75) %]
+        [% L.input_tag('shipto.shiptocity', SELF.shipto.shiptocity,  size = 30, maxlength = 75) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'Country' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('shipto.shiptocountry', SELF.shipto.shiptocountry,  size = 35, maxlength = 75) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'Contact' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('shipto.shiptocontact', SELF.shipto.shiptocontact,  size = 30, maxlength = 75) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'Phone' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('shipto.shiptophone', SELF.shipto.shiptophone,  size = 30, maxlength = 30) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'Fax' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('shipto.shiptofax', SELF.shipto.shiptofax,  size = 30, maxlength = 30) %]
+      </td>
+    </tr>
+
+    <tr>
+      <th align="right" nowrap>[% 'E-mail' | $T8 %]</th>
+
+      <td>
+        [% L.input_tag('shipto.shiptoemail', SELF.shipto.shiptoemail,  size = 45) %]
+      </td>
+    </tr>
+  </table>
+
+  [% L.button_tag('submitInputButton(this);', LxERP.t8('Delete Shipto'), name = 'action_delete_shipto', class = 'submit') %]
+  [% IF ( !SELF.shipto.shipto_id ) %]
+    <script type="text/javascript">
+      $('#action_delete_shipto').hide();
+    </script>
+  [% END %]
+</div>
diff --git a/templates/webpages/customer_vendor/tabs/vcnotes.html b/templates/webpages/customer_vendor/tabs/vcnotes.html
new file mode 100644 (file)
index 0000000..04bf951
--- /dev/null
@@ -0,0 +1,126 @@
+[%- USE T8 %]
+[%- USE HTML %]
+[%- USE L %]
+
+<div id="vcnotes">
+   [% IF ( NOTES && NOTES.size ) %]
+     <p>
+       <table>
+        <tr>
+          <th class="listheading">[% 'Delete' | $T8 %]</th>
+          <th class="listheading">[% 'Subject' | $T8 %]</th>
+          <th class="listheading">[% 'Created on' | $T8 %]</th>
+          <th class="listheading">[% 'Created by' | $T8 %]</th>
+          <th class="listheading">[% 'Follow-Up Date' | $T8 %]</th>
+          <th class="listheading">[% 'Follow-Up for' | $T8 %]</th>
+          <th class="listheading">[% 'Follow-Up done' | $T8 %]</th>
+        </tr>
+
+        [%- FOREACH row = SELF.notes %]
+          <tr class="listrow[% loop.count % 2 %]">
+            <td>
+              [% L.hidden_tag('notes[+].id', row.id) %]
+              [% IF ( !NOTE_id || (NOTE_id != row.id) ) %]
+                [% L.checkbox_tag('notes[].delete', 0) %]
+              [% END %]
+            </td>
+
+            <td>
+              <a href="ct.pl?action=edit&db=[% HTML.url(db) %]&id=[% HTML.url(id) %]&edit_note_id=[% HTML.url(row.id) %]">[% HTML.escape(row.subject) %]</a>
+            </td>
+
+            <td>
+              [% HTML.escape(row.created_on) %]
+            </td>
+
+            <td>
+              [% IF ( row.created_by_name ) %]
+                [% HTML.escape(row.created_by_name) %]
+              [% ELSE %]
+                [% HTML.escape(row.created_by_login) %]
+              [% END %]
+            </td>
+
+            <td>
+              [% HTML.escape(row.follow_up_date) %]
+            </td>
+
+            <td>
+              [% IF ( row.created_for_name ) %]
+                [% HTML.escape(row.created_for_name) %]
+              [% ELSE %]
+                [% HTML.escape(row.created_for_login) %]
+              [% END %]
+            </td>
+
+            <td>
+              [% IF ( row.follow_up_date ) %]
+                [% IF ( row.follow_up_done ) %]
+                  [% 'Yes' | $T8 %]
+                [% ELSE %]
+                  [% 'No' | $T8 %]
+                [% END %]
+              [% END %]
+            </td>
+          </tr>
+        [% END %]
+      </table>
+    </p>
+  [% END %]
+
+  <div class="listtop">
+    [% IF ( NOTE_id ) %]
+      [% 'Edit note' | $T8 %]
+    [% ELSE %]
+      [% 'Add note' | $T8 %]
+    [% END %]
+  </div>
+
+  [% L.hidden_tag('note.id', SELF.note.id) %]
+
+  <p>
+    <table>
+      <tr>
+        <td valign="right">[% 'Subject' | $T8 %]</td>
+
+        <td>
+          [% L.input_tag('note.subject', SELF.note.subject, size = 50) %]
+        </td>
+      </tr>
+
+      <tr>
+        <td valign="right" align="top">[% 'Body' | $T8 %]</td>
+
+        <td align="top">
+          [% L.textarea_tag('note.body', SELF.note.body, cols = 50 rows = 10) %]
+        </td>
+      </tr>
+
+      <tr>
+        <td valign="right">[% 'Follow-Up On' | $T8 %]</td>
+
+        <td>
+          [% L.date_tag('note_followup.follow_up_date', SELF.note_followup.follow_up_date) %]
+          [% 'for' | $T8 %]
+          [% L.select_tag(
+               'note_followup.created_for_user',
+               SELF.all_employees,
+               default = SELF.note_followup.created_for_user,
+               title_key = 'safe_name'
+             )
+          %]
+        </td>
+      </tr>
+
+      <tr>
+        <td>&nbsp;</td>
+
+        <td>
+          [% L.checkbox_tag('note_followup.done', checked = SELF.note_followup.done) %]
+          <label for="note_followup_done">[% 'Follow-Up done' | $T8 %]</label>
+        </td>
+      </tr>
+
+    </table>
+  </p>
+</div>
index 4bd57eb..3b018b4 100644 (file)
@@ -5,7 +5,7 @@
 [%- IF SELF.part.id %]
 <h3>[% LxERP.t8('Stock for part #1', SELF.part.long_description) %]</h3>
 
-[%- IF stock_empty && !SELF.part.bin_id  %]
+[%- IF SELF.stock_empty && !SELF.part.bin_id  %]
 <p>[% 'Nothing stocked yet.' | $T8 %]</p>
 [%- ELSE %]
 <table>
@@ -17,7 +17,7 @@
 [%- FOREACH wh = SELF.warehouses -%]
 [%- FOREACH bin = wh.bins -%]
   [%#- display any bins with stock and default bin -%]
-  [%- SET stock__set = stock.${bin.id} -%]
+  [%- SET stock__set = SELF.stock_by_bin.${bin.id} -%]
   [%- IF stock__set.sum > 0 || SELF.part.bin_id == bin.id -%]
   <tr class='listrow'>
     <td>[% bin.warehouse.description %]</td>
index a89b268..cb7231c 100644 (file)
@@ -1,5 +1,6 @@
 [%- USE T8 %]
 [% USE HTML %][%- USE LxERP -%]
+[% UNLESS skip_frame_header %]
  <script type="text/javascript" src="js/quicksearch_input.js"></script>
  <script type="text/javascript">
  <!--
@@ -30,6 +31,7 @@ $(clockon);
   <img src="image/[% IF MYCONFIG.stylesheet == 'lx-office-erp.css' %]spinner-blue.gif[% ELSE %]spinner-white.gif[% END %]" alt="[% LxERP.t8('Loading...') %]">
  </span>
 </div>
+[% END %]
  <div id="menuv3">
 
   [% menu %]
index a3cf406..318c95e 100644 (file)
 </div>
 
 <script type='text/javascript'>
-  var timer;
   var pp = kivi.PartPicker($('#[% FORM.real_id %]'));
   $(function(){
     $('#part_picker_filter').focus();
     pp.update_results();
   });
-  $('#part_picker_filter').keypress(function (event){
-    window.clearTimeout(timer);
-    timer = window.setTimeout(pp.update_results, 100);
-  });
+  $('#part_picker_filter').keypress(pp.update_results);
 </script>
index e156b7e..fe2d441 100644 (file)
@@ -52,7 +52,7 @@
       </td>
       <td>
        [%- 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) %]">
+        <a href="controller.pl?action=CustomerVendor/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;
index 89421a6..561baec 100644 (file)
@@ -86,7 +86,7 @@
      <tr class="listrow[% loop.count % 2 %]">
       <td>
        [%- 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) %]">
+        <a href="controller.pl?action=CustomerVendor/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>