Auth: DBUtils nicht den namespace vollmüllen lassen
[kivitendo-erp.git] / SL / Controller / CustomerVendor.pm
index d9732cb..46857cb 100644 (file)
@@ -61,6 +61,29 @@ __PACKAGE__->run_before(
     'ajaj_get_contact',
   ]
 );
+
+# make sure this comes after _load_customer_vendor
+__PACKAGE__->run_before(
+  '_check_customer_vendor_all_edit',
+  only => [
+    'edit',
+    'show',
+    'update',
+    'delete',
+    '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(
   '_create_customer_vendor',
   only => [
@@ -113,6 +136,18 @@ sub action_show {
 sub _save {
   my ($self) = @_;
 
+  my @errors = $self->{cv}->validate;
+  if (@errors) {
+    flash('error', @errors);
+    $self->_pre_render();
+    $self->render(
+      'customer_vendor/form',
+      title => ($self->is_vendor() ? t8('Edit Vendor') : t8('Edit Customer')),
+      %{$self->{template_args}}
+    );
+    ::end_of_request();
+  }
+
   my $db = $self->{cv}->db;
 
   $db->do_transaction(sub {
@@ -163,7 +198,7 @@ sub _save {
 
     $self->{shipto}->trans_id($self->{cv}->id);
     if( $self->{shipto}->shiptoname ne '' ) {
-      $self->{shipto}->save();
+      $self->{shipto}->save(cascade => 1);
     }
 
     my $snumbers = $self->is_vendor() ? 'vendornumber_'. $self->{cv}->vendornumber : 'customernumber_'. $self->{cv}->customernumber;
@@ -193,34 +228,23 @@ sub _save {
 sub action_save {
   my ($self) = @_;
 
-  if (!$self->{cv}->name) {
-    flash('error', t8('Customer missing!'));
-    $self->_pre_render();
-    $self->render(
-      'customer_vendor/form',
-      title => ($self->is_vendor() ? t8('Edit Vendor') : t8('Edit Customer')),
-      %{$self->{template_args}}
-    );
-  } else {
-
-    $self->_save();
-
-    my @redirect_params = (
-      action => 'edit',
-      id     => $self->{cv}->id,
-      db     => ($self->is_vendor() ? 'vendor' : 'customer'),
-    );
+  $self->_save();
 
-    if ( $self->{contact}->cp_id ) {
-      push(@redirect_params, contact_id => $self->{contact}->cp_id);
-    }
+  my @redirect_params = (
+    action => 'edit',
+    id     => $self->{cv}->id,
+    db     => ($self->is_vendor() ? 'vendor' : 'customer'),
+  );
 
-    if ( $self->{shipto}->shipto_id ) {
-      push(@redirect_params, shipto_id => $self->{shipto}->shipto_id);
-    }
+  if ( $self->{contact}->cp_id ) {
+    push(@redirect_params, contact_id => $self->{contact}->cp_id);
+  }
 
-    $self->redirect_to(@redirect_params);
+  if ( $self->{shipto}->shipto_id ) {
+    push(@redirect_params, shipto_id => $self->{shipto}->shipto_id);
   }
+
+  $self->redirect_to(@redirect_params);
 }
 
 sub action_save_and_close {
@@ -240,7 +264,6 @@ sub _transaction {
 
   $self->_save();
 
-  my $callback = $::form->escape($::form->{callback}, 1);
   my $name = $::form->escape($self->{cv}->name, 1);
   my $db = $self->is_vendor() ? 'vendor' : 'customer';
 
@@ -251,7 +274,7 @@ sub _transaction {
     $db .'_id' => $self->{cv}->id,
     $db        => $name,
     type       => $::form->{type},
-    callback   => $callback,
+    callback   => $::form->{callback},
   );
 
   print $::form->redirect_header($url);
@@ -493,7 +516,7 @@ sub action_get_delivery {
 
      LEFT JOIN oe
        ON (oe.ordnumber = ${arap}.ordnumber AND NOT ${arap}.ordnumber = ''
-           AND ". ($arap eq 'ar' ? 'oe.customer_id IS NOT NULL' : 'oe_vendor_id IS NOT NULL') ." )
+           AND ". ($arap eq 'ar' ? 'oe.customer_id IS NOT NULL' : 'oe.vendor_id IS NOT NULL') ." )
 
      ${where}
      ORDER BY ${arap}.transdate DESC LIMIT 15";
@@ -506,16 +529,19 @@ sub action_get_delivery {
 sub action_ajaj_get_shipto {
   my ($self) = @_;
 
-  my $data = {
+  my $data = {};
+  $data->{shipto} = {
     map(
       {
         my $name = 'shipto'. $_;
         $name => $self->{shipto}->$name;
       }
-      qw(_id name department_1 department_2 street zipcode city country contact phone fax email)
+      qw(_id name department_1 department_2 street zipcode city gln country contact phone fax email)
     )
   };
 
+  $data->{shipto_cvars} = $self->_prepare_cvar_configs_for_ajaj($self->{shipto}->cvars_by_config);
+
   $self->render(\SL::JSON::to_json($data), { type => 'json', process => 0 });
 }
 
@@ -542,29 +568,7 @@ sub action_ajaj_get_contact {
     )
   };
 
-  $data->{contact_cvars} = {
-    map {
-      my $cvar   = $_;
-      my $result = { type => $cvar->config->type };
-
-      if ($cvar->config->type eq 'number') {
-        $result->{value} = $::form->format_amount(\%::myconfig, $cvar->value, -2);
-
-      } elsif ($result->{type} =~ m{customer|vendor|part}) {
-        my $object       = $cvar->value;
-        my $method       = $result->{type} eq 'part' ? 'description' : 'name';
-
-        $result->{id}    = int($cvar->number_value) || undef;
-        $result->{value} = $object ? $object->$method // '' : '';
-
-      } else {
-        $result->{value} = $cvar->value;
-      }
-
-      ( $cvar->config->name => $result )
-
-    } grep { $_->is_valid } @{ $self->{contact}->cvars_by_config }
-  };
+  $data->{contact_cvars} = $self->_prepare_cvar_configs_for_ajaj($self->{contact}->cvars_by_config);
 
   $self->render(\SL::JSON::to_json($data), { type => 'json', process => 0 });
 }
@@ -596,6 +600,7 @@ sub action_ajaj_autocomplete {
     if (1 == scalar @{ $exact_matches = $manager->get_all(
       query => [
         obsolete => 0,
+        (salesman_id => SL::DB::Manager::Employee->current->id) x !$::auth->assert('customer_vendor_all_edit', 1),
         or => [
           name    => { ilike => $::form->{filter}{'all:substr:multi::ilike'} },
           $number => { ilike => $::form->{filter}{'all:substr:multi::ilike'} },
@@ -682,6 +687,17 @@ sub is_orphaned {
   return $self->{_is_orphaned} = !$dummy;
 }
 
+sub _copy_form_to_cvars {
+  my ($self, %params) = @_;
+
+  foreach my $cvar (@{ $params{target}->cvars_by_config }) {
+    my $value = $params{source}->{$cvar->config->name};
+    $value    = $::form->parse_amount(\%::myconfig, $value) if $cvar->config->type eq 'number';
+
+    $cvar->value($value);
+  }
+}
+
 sub _instantiate_args {
   my ($self) = @_;
 
@@ -704,16 +720,6 @@ sub _instantiate_args {
 
   $self->{cv}->hourly_rate($::instance_conf->get_customer_hourly_rate) if $self->is_customer && !$self->{cv}->hourly_rate;
 
-  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();
     $self->{note_followup} = $self->{note}->follow_up;
@@ -750,15 +756,9 @@ sub _instantiate_args {
   }
   $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);
-  }
+  $self->_copy_form_to_cvars(target => $self->{cv},      source => $::form->{cv_cvars});
+  $self->_copy_form_to_cvars(target => $self->{contact}, source => $::form->{contact_cvars});
+  $self->_copy_form_to_cvars(target => $self->{shipto},  source => $::form->{shipto_cvars});
 }
 
 sub _load_customer_vendor {
@@ -801,6 +801,16 @@ sub _load_customer_vendor {
   }
 }
 
+sub _check_customer_vendor_all_edit {
+  my ($self) = @_;
+
+  unless ($::auth->assert('customer_vendor_all_edit', 1)) {
+    die($::locale->text("You don't have the rights to edit this customer.") . "\n")
+      if $self->{cv}->is_customer and
+         SL::DB::Manager::Employee->current->id != $self->{cv}->salesman_id;
+  };
+};
+
 sub _create_customer_vendor {
   my ($self) = @_;
 
@@ -920,6 +930,37 @@ sub _pre_render {
   $::request->{layout}->add_javascripts('kivi.CustomerVendor.js');
 }
 
+sub _prepare_cvar_configs_for_ajaj {
+  my ($self, $cvars) = @_;
+
+  return {
+    map {
+      my $cvar   = $_;
+      my $result = { type => $cvar->config->type };
+
+      if ($cvar->config->type eq 'number') {
+        $result->{value} = $::form->format_amount(\%::myconfig, $cvar->value, -2);
+
+      } elsif ($result->{type} eq 'date') {
+        $result->{value} = $cvar->value ? $cvar->value->to_kivitendo : undef;
+
+      } elsif ($result->{type} =~ m{customer|vendor|part}) {
+        my $object       = $cvar->value;
+        my $method       = $result->{type} eq 'part' ? 'description' : 'name';
+
+        $result->{id}    = int($cvar->number_value) || undef;
+        $result->{value} = $object ? $object->$method // '' : '';
+
+      } else {
+        $result->{value} = $cvar->value;
+      }
+
+      ( $cvar->config->name => $result )
+
+    } grep { $_->is_valid } @{ $cvars }
+  };
+}
+
 sub normalize_name {
   my ($self) = @_;
 
@@ -958,6 +999,9 @@ sub init_customer_models {
       },
       customernumber => t8('Customer Number'),
     },
+    query => [
+     ( salesman_id => SL::DB::Manager::Employee->current->id) x !$::auth->assert('customer_vendor_all_edit', 1),
+    ],
   );
 }