kivi.Validator: check_right_*_format in display_row auf Validator geƤndert
[kivitendo-erp.git] / bin / mozilla / io.pl
index e5b88c4..19f0c9a 100644 (file)
@@ -63,6 +63,7 @@ use SL::DB::Vendor;
 use SL::Helper::CreatePDF;
 use SL::Helper::Flash;
 use SL::Helper::PrintOptions;
+use SL::Helper::ShippedQty;
 
 require "bin/mozilla/common.pl";
 
@@ -218,7 +219,7 @@ sub display_row {
 
   # special alignings
   my %align  = map { $_ => 'right' } qw(qty ship right discount linetotal stock_in_out weight ship_missing);
-  my %nowrap = map { $_ => 1 }       qw(description unit);
+  my %nowrap = map { $_ => 1 }       qw(description unit  price_source);
 
   $form->{marge_total}           = 0;
   $form->{sellprice_total}       = 0;
@@ -336,24 +337,18 @@ sub display_row {
       $column_data{ship_missing} = $form->format_amount(\%myconfig, $ship_missing_qty) . ' ' . $form->{"unit_$i"} . '; ' . $form->format_amount(\%myconfig, $ship_missing_amount, $decimalplaces);
     }
 
-    my $sellprice_value = $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces);
-    my $discount_value  = $form->format_amount(\%myconfig, $form->{"discount_$i"});
-    my $edit_prices     = $main::auth->assert('edit_prices', 1) && !$::form->{"active_price_source_$i"};
-    my $edit_discounts  = $main::auth->assert('edit_prices', 1) && !$::form->{"active_discount_source_$i"};
-    $column_data{sellprice}   = (!$edit_prices)
-                                ? $cgi->hidden(   -name => "sellprice_$i", -id => "sellprice_$i", -value => $sellprice_value) . $sellprice_value
-                                : $cgi->textfield(-name => "sellprice_$i", -id => "sellprice_$i", -size => 10, -onBlur => "check_right_number_format(this)", -value => $sellprice_value);
-    $column_data{discount}    = (!$edit_discounts)
-                                  ? $cgi->hidden(   -name => "discount_$i", -id => "discount_$i", -value => $discount_value) . $discount_value . ' %'
-                                  : $cgi->textfield(-name => "discount_$i", -id => "discount_$i", -size => 3, -value => $discount_value);
     $column_data{linetotal}   = $form->format_amount(\%myconfig, $linetotal, 2);
     $column_data{bin}         = $form->{"bin_$i"};
 
     $column_data{weight}      = $form->format_amount(\%myconfig, $form->{"qty_$i"} * $form->{"weight_$i"}, 3) . ' ' . $defaults->{weightunit} if $defaults->{show_weight};
 
+    my $sellprice_value = $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces);
+    my $discount_value  = $form->format_amount(\%myconfig, $form->{"discount_$i"});
+
+    my $price;
     if ($form->{"id_${i}"} && !$is_delivery_order) {
       my $price_source  = SL::PriceSource->new(record_item => $record_item, record => $record);
-      my $price         = $price_source->price_from_source($::form->{"active_price_source_$i"});
+         $price         = $price_source->price_from_source($::form->{"active_price_source_$i"});
       my $discount      = $price_source->discount_from_source($::form->{"active_discount_source_$i"});
       my $best_price    = $price_source->best_price;
       my $best_discount = $price_source->best_discount;
@@ -378,6 +373,15 @@ sub display_row {
       }
     }
 
+    my $edit_prices     = $main::auth->assert('edit_prices', 1) && (!$::form->{"active_price_source_$i"} || !$price || $price->editable);
+    my $edit_discounts  = $main::auth->assert('edit_prices', 1) && !$::form->{"active_discount_source_$i"};
+    $column_data{sellprice}   = (!$edit_prices)
+                                ? $cgi->hidden(   -name => "sellprice_$i", -id => "sellprice_$i", -value => $sellprice_value) . $sellprice_value
+                                : $cgi->textfield(-name => "sellprice_$i", -id => "sellprice_$i", -size => 10, -onBlur => "check_right_number_format(this)", -value => $sellprice_value);
+    $column_data{discount}    = (!$edit_discounts)
+                                  ? $cgi->hidden(   -name => "discount_$i", -id => "discount_$i", -value => $discount_value) . $discount_value . ' %'
+                                  : $cgi->textfield(-name => "discount_$i", -id => "discount_$i", -size => 3, -value => $discount_value);
+
     if ($is_delivery_order) {
       $column_data{stock_in_out} =  calculate_stock_in_out($i);
     }
@@ -389,7 +393,7 @@ sub display_row {
       '-labels' => \%projectnumber_labels,
       '-default' => $form->{"project_id_$i"}
     ));
-    $column_data{reqdate}   = qq|<input name="reqdate_$i" size="11" onchange="check_right_date_format(this)" value="$form->{"reqdate_$i"}">|;
+    $column_data{reqdate}   = qq|<input name="reqdate_$i" size="11" data-validate="date" value="$form->{"reqdate_$i"}">|;
     $column_data{subtotal}  = sprintf qq|<input type="checkbox" name="subtotal_$i" value="1" %s>|, $form->{"subtotal_$i"} ? 'checked' : '';
 
 # begin marge calculations
@@ -557,13 +561,15 @@ sub item_selected {
   my $row = $curr_row;
 
   if ($myconfig{item_multiselect}) {
-    foreach (grep(/^select_qty_/, keys(%{ $form }))) {
+    my %multi_items;
+    for (keys %$form) {
       next unless $form->{$_};
-      $_ =~ /^select_qty_(\d+)/;
-      $form->{"id_${row}"}  = $1;
-      $form->{"qty_${row}"} = $form->{$_};
+      next unless /^select_qty_(\d+)/;
+      $multi_items{"id_${row}"}  = $1;
+      $multi_items{"qty_${row}"} = $form->{$_};
       $row++;
     }
+    $form->{$_} = $multi_items{$_} for keys %multi_items;
   } else {
     $form->{"id_${row}"} = delete($form->{select_item_id}) || croak 'Missing item selection ID';
     $row++;
@@ -692,34 +698,39 @@ sub item_selected {
 }
 
 sub new_item {
-  $main::lxdebug->enter_sub();
+  _check_io_auth();
 
-  my $form     = $main::form;
-  my %myconfig = %main::myconfig;
+  my $price = $::form->{vc} eq 'customer' ? 'sellprice_as_number' : 'lastcost_as_number';
+  my $previousform = $::auth->save_form_in_session;
+  my $callback     = build_std_url("action=return_from_new_item", "previousform=$previousform");
+  my $i            = $::form->{rowcount};
 
-  _check_io_auth();
+  my $parts_classification_type = $::form->{vc} eq 'customer' ? 'sales' : 'purchases';
+
+  my @HIDDENS;
+  push @HIDDENS,      { 'name' => 'callback',     'value' => $callback };
+  push @HIDDENS, map +{ 'name' => $_,             'value' => $::form->{$_} },        qw(rowcount vc);
+  push @HIDDENS, map +{ 'name' => "part.$_",      'value' => $::form->{"${_}_$i"} }, qw(partnumber description unit price_factor_id);
+  push @HIDDENS,      { 'name' => "part.$price",  'value' => $::form->{"sellprice_$i"} };
+  push @HIDDENS,      { 'name' => "part.notes",   'value' => $::form->{"longdescription_$i"} };
 
-  my $price_key = ($form->{type} =~ m/request_quotation|purchase_order/) || ($form->{script} eq 'ir.pl') ? 'lastcost' : 'sellprice';
+  push @HIDDENS,      { 'name' => "parts_classification_type", 'value' => $parts_classification_type };
 
-  # change callback
-  $form->{old_callback} = $form->escape($form->{callback}, 1);
-  $form->{callback}     = $form->escape("$form->{script}?action=display_form", 1);
+  $::form->header;
+  print $::form->parse_html_template("generic/new_item", { HIDDENS => [ sort { $a->{name} cmp $b->{name} } @HIDDENS ] } );
+}
 
-  # save all form variables except action in the session and keep the key in the previousform variable
-  my $previousform = $::auth->save_form_in_session(skip_keys => [ qw(action) ]);
+sub return_from_new_item {
+  _check_io_auth();
 
-  my @HIDDENS;
-  push @HIDDENS,      { 'name' => 'previousform', 'value' => $previousform };
-  push @HIDDENS, map +{ 'name' => $_,             'value' => $form->{$_} },                       qw(rowcount vc);
-  push @HIDDENS, map +{ 'name' => $_,             'value' => $form->{"${_}_$form->{rowcount}"} }, qw(partnumber description unit);
-  push @HIDDENS,      { 'name' => 'taxaccount2',  'value' => $form->{taxaccounts} };
-  push @HIDDENS,      { 'name' => $price_key,     'value' => $form->parse_amount(\%myconfig, $form->{"sellprice_$form->{rowcount}"}) };
-  push @HIDDENS,      { 'name' => 'notes',        'value' => $form->{"longdescription_$form->{rowcount}"} };
+  my $part = SL::DB::Manager::Part->find_by(id => delete $::form->{new_parts_id}) or die 'can not find part that was just saved!';
 
-  $form->header();
-  print $form->parse_html_template("generic/new_item", { HIDDENS => [ sort { $a->{name} cmp $b->{name} } @HIDDENS ] } );
+  $::auth->restore_form_from_session(delete $::form->{previousform}, form => $::form);
 
-  $main::lxdebug->leave_sub();
+  $::form->{"id_$::form->{rowcount}"} = $part->id;
+
+  my $url = build_std_url("script=$::form->{script}", "RESTORE_FORM_FROM_SESSION_ID=" . $::auth->save_form_in_session);
+  print $::request->{cgi}->redirect($url);
 }
 
 sub check_form {
@@ -895,7 +906,7 @@ sub order {
   $form->{old_employee_id} = $form->{employee_id};
   $form->{old_salesman_id} = $form->{salesman_id};
 
-  delete $form->{$_} foreach (qw(printed emailed queued));
+  delete $form->{$_} foreach (qw(id printed emailed queued));
 
   # When creating a new sales order from a saved sales invoice, reset id,
   # ordnumber, transdate and deliverydate as we are creating a new order. This
@@ -976,7 +987,7 @@ sub quotation {
   if ($form->{second_run}) {
     $form->{print_and_post} = 0;
   }
-  delete $form->{$_} foreach (qw(printed emailed queued));
+  delete $form->{$_} foreach (qw(id printed emailed queued));
 
   my $buysell;
   if ($form->{script} eq 'ir.pl' || $form->{type} eq 'purchase_order') {
@@ -1659,37 +1670,14 @@ sub _update_part_information {
 }
 
 sub _update_ship {
-  $main::lxdebug->enter_sub();
-
-  my $form     = $main::form;
-  my %myconfig = %main::myconfig;
-
-  if (!$form->{ordnumber} || !$form->{id}) {
-    map { $form->{"ship_$_"} = 0 } (1..$form->{rowcount});
-    $main::lxdebug->leave_sub();
-    return;
-  }
-
-  my $all_units = AM->retrieve_all_units();
-
-  my %ship = DO->get_shipped_qty('oe_id' => $form->{id});
-
-  foreach my $i (1..$form->{rowcount}) {
-    next unless ($form->{"id_${i}"});
-
-    $form->{"ship_$i"} = 0;
-
-    my $ship_entry = $ship{$i};
+  return unless $::form->{id};
+  my $helper = SL::Helper::ShippedQty->new->calculate($::form->{id});
 
-    next if (!$ship_entry || ($ship_entry->{qty_ordered} <= 0));
-
-    my $rowqty = $ship_entry->{qty_ordered} - $ship_entry->{qty_notdelivered};
-    $rowqty   *= $all_units->{$form->{"unit_$i"}}->{factor} /
-                 $all_units->{$form->{"partunit_$i"}}->{factor} if !$form->{simple_save};
-    $form->{"ship_$i"}  = $rowqty;
+  for my $i (1..$::form->{rowcount}) {
+    if (my $oid = $::form->{"orderitems_id_$i"}) {
+      $::form->{"ship_$i"} = $helper->shipped_qty->{$oid};
+    }
   }
-
-  $main::lxdebug->leave_sub();
 }
 
 sub _update_custom_variables {
@@ -1828,25 +1816,44 @@ sub _make_record_item {
 
   $class = 'SL::DB::' . $class;
 
+  my %translated_methods = (
+    'SL::DB::OrderItem' => {
+      id                      => 'parts_id',
+      orderitems_id           => 'id',
+    },
+    'SL::DB::DeliveryOrderItem' => {
+      id                      => 'parts_id',
+      delivery_order_items_id => 'id',
+    },
+    'SL::DB::InvoiceItem' => {
+      id                      => 'parts_id',
+      invoice_id => 'id',
+    },
+  );
+
   eval "require $class";
 
   my $obj = $::form->{"orderitems_id_$row"}
           ? $class->meta->convention_manager->auto_manager_class_name->find_by(id => $::form->{"orderitems_id_$row"})
           : $class->new;
 
-  for my $method (apply { s/_$row$// } grep { /_$row$/ } keys %$::form) {
+  for my $key (grep { /_$row$/ } keys %$::form) {
+    my $method = $key;
+    $method =~ s/_$row$//;
+    $method = $translated_methods{$class}{$method} // $method;
+    my $value = $::form->{$key};
     if ($obj->meta->column($method)) {
       if ($obj->meta->column($method)->isa('Rose::DB::Object::Metadata::Column::Date')) {
-        $obj->${\"$method\_as_date"}($::form->{"$method\_$row"});
+        $obj->${\"$method\_as_date"}($value);
       } elsif ((ref $obj->meta->column($method)) =~ /^Rose::DB::Object::Metadata::Column::(?:Numeric|Float|DoublePrecsion)$/) {
-        $obj->${\"$method\_as_number"}($::form->{"$method\_$row"});
+        $obj->${\"$method\_as_number"}($value);
       } elsif ((ref $obj->meta->column($method)) =~ /^Rose::DB::Object::Metadata::Column::Boolean$/) {
-        $obj->$method(!!$::form->{$method});
+        $obj->$method(!!$value);
       } else {
-        $obj->$method($::form->{"$method\_$row"});
+        $obj->$method($value);
       }
     } else {
-      $obj->{__additional_form_attributes}{$method} = $::form->{"$method\_$row"};
+      $obj->{__additional_form_attributes}{$method} = $value;
     }
   }
 
@@ -1930,10 +1937,12 @@ sub _get_files_for_email_dialog {
 
   return %files if !$::instance_conf->get_doc_storage;
 
-  $files{versions} = [ SL::File->get_all_versions(object_id => $::form->{id},    object_type => $::form->{type}, file_type => 'document') ];
-  $files{files}    = [ SL::File->get_all(         object_id => $::form->{id},    object_type => $::form->{type}, file_type => 'attachment') ];
-  $files{vc_files} = [ SL::File->get_all(         object_id => $::form->{vc_id}, object_type => $::form->{vc},   file_type => 'attachment') ]
-    if $::form->{vc} && $::form->{"vc_id"};
+  if ($::form->{id}) {
+    $files{versions} = [ SL::File->get_all_versions(object_id => $::form->{id},    object_type => $::form->{type}, file_type => 'document') ];
+    $files{files}    = [ SL::File->get_all(         object_id => $::form->{id},    object_type => $::form->{type}, file_type => 'attachment') ];
+    $files{vc_files} = [ SL::File->get_all(         object_id => $::form->{vc_id}, object_type => $::form->{vc},   file_type => 'attachment') ]
+      if $::form->{vc} && $::form->{"vc_id"};
+  }
 
   my @parts =
     uniq_by { $_->{id} }
@@ -1957,10 +1966,22 @@ sub _get_files_for_email_dialog {
 }
 
 sub show_sales_purchase_email_dialog {
-  my $contact    = $::form->{cp_id} ? SL::DB::Contact->load_cached($::form->{cp_id}) : undef;
+  my $email = '';
+  if ($::form->{cp_id}) {
+    $email = SL::DB::Contact->load_cached($::form->{cp_id})->cp_email;
+  }
+
+  if (!$email && $::form->{vc} && $::form->{vc_id}) {
+    $email = SL::DB::Customer->load_cached($::form->{vc_id})->email if 'customer' eq $::form->{vc};
+    $email = SL::DB::Vendor  ->load_cached($::form->{vc_id})->email if 'vendor'   eq $::form->{vc};
+  }
+
+  $email = '' if $::form->{type} eq 'purchase_delivery_order';
+
   my $email_form = {
-    to                  => $contact ? $contact->cp_email : '',
+    to                  => $email,
     subject             => $::form->generate_email_subject,
+    message             => $::form->generate_email_body,
     attachment_filename => $::form->generate_attachment_filename,
   };