ct.pl als Controller
authorThomas Heck <theck@linet-services.de>
Mon, 24 Jun 2013 08:37:42 +0000 (10:37 +0200)
committerJan Büren <jan@kivitendo-premium.de>
Thu, 18 Jul 2013 07:09:01 +0000 (09:09 +0200)
SL/Controller/CustomerVendor.pm [new file with mode: 0644]
js/kivi.CustomerVendor.js [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]

diff --git a/SL/Controller/CustomerVendor.pm b/SL/Controller/CustomerVendor.pm
new file mode 100644 (file)
index 0000000..e64e4b5
--- /dev/null
@@ -0,0 +1,747 @@
+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;
+
+# 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_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 => [
+    'new',
+  ]
+);
+
+sub action_new {
+  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 $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();
+  }
+
+  #TODO: history
+}
+
+sub action_save {
+  my ($self) = @_;
+
+  $self->_save();
+
+  $self->action_edit();
+}
+
+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 =
+    $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) = @_;
+
+  if( !$self->is_orphaned() ) {
+    SL::Helper::Flash::flash('error', $::locale->text('blaabla'));
+
+    $self->action_edit();
+  }
+  else {
+    $self->{cv}->delete();
+
+    #TODO: history
+
+    my $msg = $self->is_vendor() ? $::locale->text('Vendor deleted!') : $::locale->text('Customer deleted!');
+    $::form->redirect($msg);
+  }
+
+}
+
+
+sub action_delete_contact {
+  my ($self) = @_;
+
+  if ( !$self->{contact}->cp_id ) {
+    SL::Helper::Flash::flash('error', $::locale->text('No contact selected to delete'));
+  } else {
+    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();
+      SL::Helper::Flash::flash('info', $::locale->text('Contact deleted.'));
+    }
+
+    $self->{contact} = SL::DB::Contact->new();
+  }
+
+  $self->action_edit();
+}
+
+sub action_delete_shipto {
+  my ($self) = @_;
+
+  if ( !$self->{shipto}->shipto_id ) {
+    SL::Helper::Flash::flash('error', $::locale->text('No shipto selected to delete'));
+  } else {
+    if ( $self->{shipto}->used ) {
+      $self->{shipto}->detach();
+      $self->{shipto}->save();
+      SL::Helper::Flash::flash('info', $::locale->text('Shipto is in use and was flagged invalid.'));
+    } else {
+      $self->{shipto}->delete();
+      SL::Helper::Flash::flash('info', $::locale->text('Shipto deleted.'));
+    }
+
+    $self->{shipto} = SL::DB::Shipto->new();
+  }
+
+  $self->action_edit();
+}
+
+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;
+
+  foreach ( 'cv.creditlimit', 'cv.discount' ) {
+    my ($namespace, $varname) = split('.', $_, 2);
+    $::form->{$namespace}->{$varname} = $::form->parse_amount(\%::myconfig, $::form->{$namespace}->{$varname});
+  }
+  $::form->{cv}->{discount} /= 100;
+
+  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);
+  }
+
+#  foreach my $cvar_key (keys(%{$::form->{cv_cvars}})) {
+#    my $cvar_value = $::form->{cv_cvars}->{$cvar_key};
+#    my $cvar = $self->{cv}->cvar_by_name($cvar_key);
+#    $cvar->value($cvar_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');
+  #  if ( $self->{note}->trans_id != $self->{cv}->id ) {
+  #    die($::locale->text('Error'));
+  #  }
+
+
+  $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 ( $self->{shipto}->trans_id != $self->{cv}->id ) {
+#    die($::locale->text('Error'));
+#  }
+
+  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}});
+#  if ( $self->{contact}->cp_cv_id != $self->{cv}->id ) {
+#    die($::locale->text('Error'));
+#  }
+
+  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) = @_;
+
+  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 =
+    '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)
+    )
+  ];
+
+  $query =
+    'SELECT curr
+     FROM defaults';
+  my $curr = selectall_hashref_query($::form, $dbh, $query)->[0]->{curr};
+  my @currencies = grep(
+    { $_; }
+    map(
+      { s/\s//g; $_; }
+      split(m/:/, $curr)
+    )
+  );
+  $self->{all_currencies} = \@currencies;
+
+  $self->{all_languages} = SL::DB::Manager::Language->get_all();
+
+  $self->{all_taxzones} = SL::DB::Manager::TaxZone->get_all();
+
+  #Employee:
+  #TODO: ALL_SALESMAN
+  #TODO: ALL_SALESMAN_CUSTOMERS
+
+  $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} = {};
+
+  $self->{cv}->discount($self->{cv}->discount * 100);
+
+
+  $::request->{layout}->add_javascripts('autocomplete_customer.js');
+}
+
+1;
diff --git a/js/kivi.CustomerVendor.js b/js/kivi.CustomerVendor.js
new file mode 100644 (file)
index 0000000..371434c
--- /dev/null
@@ -0,0 +1,103 @@
+namespace('kivi.CustomerVendor', function() {
+
+  this.selectShipto = function() {
+    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();
+      });
+    }
+    else {
+      $('#shipto :input').not(':button, :submit, :reset, :hidden').val('');
+
+      $('#action_delete_shipto').hide();
+    }
+  };
+
+  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() {
+    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();
+      });
+    }
+    else {
+      $('#contacts :input').not(':button, :submit, :reset, :hidden').val('').removeAttr('checked').removeAttr('selected');
+
+      $('#action_delete_contact').hide();
+    }
+
+    $('#contact_cp_title_select, #contact_cp_abteilung_select').val('');
+  };
+
+
+  this.showMap = function(prefix) {
+    var searchStmts = [
+      '#street',
+      ', ',
+      '#zipcode',
+      ' ',
+      '#city',
+      ', ',
+      '#country'
+    ];
+
+    var searchString = "";
+
+    for(var i in searchStmts) {
+      var stmt = searchStmts[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();
+  };
+
+  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);
+  };
+});
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..e29d097
--- /dev/null
@@ -0,0 +1,993 @@
+[%- USE T8 %]
+[%- USE HTML %]
+[%- 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">
+    <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>
+
+    <div id="billing">
+      <table width="100%">
+
+        <tr height="5"></tr>
+
+        [% IF ( conf_vertreter ) %]<!-- == $::lx_office_conf{features}->{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>
+              <!-- TODO: ALL_SALESMAN_CUSTOMERS -->
+              [% L.select_tag('cv.salesman_id', SELF.all_employees, value_key = 'id', title_key = 'safe_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) %]
+            <a href="#" onclick="namespace('kivi.CustomerVendor').showMap('cv_');" title="[% 'Map' | $T8 %]">
+              <img src="image/map.png" alt="[% 'Map' | $T8 %]" />
+            </a>
+          </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" 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', LxERP.format_amount(SELF.cv.creditlimit, 0), 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', SELF.cv.discount, 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.curr', SELF.all_currencies, default = SELF.cv.curr, 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>
+
+
+          <th align="right">[% 'Bcc' | $T8 %]</th>
+
+          <td>
+            [% L.input_tag('cv.bcc', SELF.cv.bcc, size = 40) %]
+          </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>
+              <!-- TODO: ALL_SALESMAN -->
+              [% L.select_tag('cv.salesman_id', SELF.all_employees, default = salesman_id, value_key = 'id', title_key = 'safe_name', with_empty = 1) %]
+            </td>
+
+            <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>
+          [%- END %]
+        </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>
+
+    <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 = "namespace('kivi.CustomerVendor').selectShipto();"
+               )
+            %]
+          </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) %]
+
+            <a href="#" onclick="namespace('kivi.CustomerVendor').showMap('shipto_shipto');" title="[% 'Map' | $T8 %]">
+              <img src="image/map.png" alt="[% 'Map' | $T8 %]" />
+            </a>
+          </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>
+
+    <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 = "namespace('kivi.CustomerVendor').selectContact();")
+            %]
+          </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) %]
+
+            <a href="#" onclick="namespace('kivi.CustomerVendor').showMap('contact_cp_');" title="[% 'Map' | $T8 %]">
+              <img src="image/map.png" alt="[% 'Map' | $T8 %]" />
+            </a>
+          </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">
+                [%
+                  INCLUDE '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>
+
+    <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 = "namespace('kivi.CustomerVendor').selectDelivery();"
+              )
+            %]
+          </td>
+        </tr>
+
+        <tr>
+          <th align="right" nowrap>[% 'From' | $T8 %]</th>
+
+          <td>
+            [%
+              L.date_tag(
+                'delivery_from',
+                FORM.delivery_from,
+                onchange => "namespace('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 => "namespace('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>
+
+
+     <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>
+
+    [% IF ( cv_cvars.size ) %]
+      <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">
+                  [%
+                    INCLUDE 'customer_vendor/render_cvar_input.html'
+                            cvar_name_prefix = 'cv_cvars.'
+                  %]
+                </td>
+              </tr>
+            [% END %]
+          </table>
+        </p>
+      </div>
+    [% 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="namespace('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 %]