]> wagnertech.de Git - mfinanz.git/blobdiff - SL/Controller/Order.pm
Auftrags-Controller: Name der Druckvorlage und Download-Datei nicht fest verdrahten.
[mfinanz.git] / SL / Controller / Order.pm
index 8c3ca542724ab7c3e420e8d96c521d1d137ff030..25eae7a9b62f1b0e5f9dfe3b3dab0e1ffef4130c 100644 (file)
@@ -4,10 +4,10 @@ use strict;
 use parent qw(SL::Controller::Base);
 
 use SL::Helper::Flash;
-use SL::ClientJS;
 use SL::Presenter;
 use SL::Locale::String;
 use SL::SessionFile::Random;
+use SL::PriceSource;
 use SL::Form;
 
 use SL::DB::Order;
@@ -18,6 +18,7 @@ use SL::DB::Employee;
 use SL::DB::Project;
 use SL::DB::Default;
 use SL::DB::Unit;
+use SL::DB::Price;
 
 use SL::Helper::DateTime;
 use SL::Helper::CreatePDF qw(:all);
@@ -25,10 +26,11 @@ use SL::Helper::CreatePDF qw(:all);
 use List::Util qw(max first);
 use List::MoreUtils qw(none pairwise);
 use English qw(-no_match_vars);
+use File::Spec;
 
 use Rose::Object::MakeMethods::Generic
 (
- 'scalar --get_set_init' => [ qw(order valid_types type cv js p) ],
+ 'scalar --get_set_init' => [ qw(order valid_types type cv p) ],
 );
 
 
@@ -38,6 +40,8 @@ __PACKAGE__->run_before('_check_auth');
 __PACKAGE__->run_before('_recalc',
                         only => [ qw(edit update save save_and_delivery_order create_pdf send_email) ]);
 
+__PACKAGE__->run_before('_get_unalterable_data',
+                        only => [ qw(save save_and_delivery_order create_pdf send_email) ]);
 
 #
 # actions
@@ -91,7 +95,7 @@ sub action_save {
 
   if (scalar @{ $errors }) {
     $self->js->flash('error', $_) foreach @{ $errors };
-    return $self->js->render($self);
+    return $self->js->render();
   }
 
   flash_later('info', $::locale->text('The order has been saved'));
@@ -117,19 +121,25 @@ sub action_create_pdf {
   $sfile->fh->print($pdf);
   $sfile->fh->close;
 
-  my $tmp_filename = $sfile->file_name;
-  my $pdf_filename = t8('Sales Order') . '_' . $self->order->ordnumber . '.pdf';
+  my $key = join('_', Time::HiRes::gettimeofday(), int rand 1000000000000);
+  $::auth->set_session_value("Order::create_pdf-${key}" => $sfile->file_name);
+
+  $::form->{formname}  = $self->type;
+  $::form->{language} = 'de';
+  my $pdf_filename =  $::form->get_formname_translation . '_' . $self->order->ordnumber . '.pdf';
 
   $self->js
-    ->run('download_pdf', $tmp_filename, $pdf_filename)
+    ->run('download_pdf', $pdf_filename, $key)
     ->flash('info', t8('The PDF has been created'))->render($self);
 }
 
 sub action_download_pdf {
   my ($self) = @_;
 
+  my $key = $::form->{key};
+  my $tmp_filename = $::auth->get_session_value("Order::create_pdf-${key}");
   return $self->send_file(
-    $::form->{tmp_filename},
+    $tmp_filename,
     type => 'application/pdf',
     name => $::form->{pdf_filename},
   );
@@ -183,12 +193,8 @@ sub action_send_email {
     return $self->js->flash('error', t8('Conversion to PDF failed: #1', $errors[0]))->render($self);
   }
 
-  my $sfile = SL::SessionFile::Random->new(mode => "w");
-  $sfile->fh->print($pdf);
-  $sfile->fh->close;
-
-  $mail->{attachments} = [{ "filename" => $sfile->file_name,
-                            "name"     => $::form->{email}->{attachment_filename} }];
+  $mail->{attachments} = [{ "content" => $pdf,
+                            "name"    => $::form->{email}->{attachment_filename} }];
 
   if (my $err = $mail->send) {
     return $self->js->flash('error', t8('Sending E-mail: ') . $err)
@@ -219,7 +225,7 @@ sub action_save_and_delivery_order {
 
   if (scalar @{ $errors }) {
     $self->js->flash('error', $_) foreach @{ $errors };
-    return $self->js->render($self);
+    return $self->js->render();
   }
 
   my $delivery_order = $self->order->convert_to_delivery_order($self->order);
@@ -239,31 +245,39 @@ sub action_save_and_delivery_order {
 sub action_customer_vendor_changed {
   my ($self) = @_;
 
-  if ($self->cv eq 'customer') {
-    $self->order->customer(SL::DB::Manager::Customer->find_by_or_create(id => $::form->{cv_id}));
-
-  } elsif ($self->cv eq 'vendor') {
-    $self->order->vendor(SL::DB::Manager::Vendor->find_by_or_create(id => $::form->{cv_id}));
-  }
+  my $cv_method = $self->cv;
 
-  if ($self->order->{$self->cv}->contacts && scalar @{ $self->order->{$self->cv}->contacts } > 0) {
+  if ($self->order->$cv_method->contacts && scalar @{ $self->order->$cv_method->contacts } > 0) {
     $self->js->show('#cp_row');
   } else {
     $self->js->hide('#cp_row');
   }
 
-  if ($self->order->{$self->cv}->shipto && scalar @{ $self->order->{$self->cv}->shipto } > 0) {
+  if ($self->order->$cv_method->shipto && scalar @{ $self->order->$cv_method->shipto } > 0) {
     $self->js->show('#shipto_row');
   } else {
     $self->js->hide('#shipto_row');
   }
 
+  $self->order->taxzone_id($self->order->$cv_method->taxzone_id);
+
+  if ($self->order->is_sales) {
+    $self->order->taxincluded(defined($self->order->$cv_method->taxincluded_checked)
+                              ? $self->order->$cv_method->taxincluded_checked
+                              : $::myconfig{taxincluded_checked});
+  }
+
+  $self->_recalc();
+
   $self->js
-    ->replaceWith('#order_cp_id',     $self->build_contact_select)
-    ->replaceWith('#order_shipto_id', $self->build_shipto_select)
-    ->val('#order_taxzone_id', $self->order->{$self->cv}->taxzone_id)
-    ->focus('#order_' . $self->cv . '_id')
-    ->render($self);
+    ->replaceWith('#order_cp_id',       $self->build_contact_select)
+    ->replaceWith('#order_shipto_id',   $self->build_shipto_select)
+    ->val(        '#order_taxzone_id',  $self->order->taxzone_id)
+    ->val(        '#order_taxincluded', $self->order->taxincluded)
+    ->focus(      '#order_' . $self->cv . '_id');
+
+  $self->_js_redisplay_amounts_and_taxes;
+  $self->js->render();
 }
 
 sub action_add_item {
@@ -280,12 +294,17 @@ sub action_add_item {
   my $cv_method   = $self->cv;
   my $cv_discount = $self->order->$cv_method? $self->order->$cv_method->discount : 0.0;
 
+  my $price = $item->sellprice;
+  $price  ||= ($self->order->$cv_method && $self->order->$cv_method->klass)
+            ? (SL::DB::Manager::Price->find_by(parts_id => $part->id, pricegroup_id => $self->order->$cv_method->klass)->price || $part->sellprice)
+            : $part->sellprice;
+
   my %new_attr;
   $new_attr{part}        = $part;
   $new_attr{description} = $part->description if ! $item->description;
   $new_attr{qty}         = 1.0                if ! $item->qty;
   $new_attr{unit}        = $part->unit;
-  $new_attr{sellprice}   = $part->sellprice   if ! $item->sellprice;
+  $new_attr{sellprice}   = $price;
   $new_attr{discount}    = $cv_discount       if ! $item->discount;
 
   # add_custom_variables adds cvars to an orderitem with no cvars for saving, but
@@ -316,7 +335,7 @@ sub action_add_item {
     ->focus('#add_item_parts_id_name');
 
   $self->_js_redisplay_amounts_and_taxes;
-  $self->js->render($self);
+  $self->js->render();
 }
 
 sub action_recalc_amounts_and_taxes {
@@ -326,7 +345,7 @@ sub action_recalc_amounts_and_taxes {
 
   $self->_js_redisplay_linetotals;
   $self->_js_redisplay_amounts_and_taxes;
-  $self->js->render($self);
+  $self->js->render();
 }
 
 sub _js_redisplay_linetotals {
@@ -387,10 +406,6 @@ sub init_cv {
   return $cv;
 }
 
-sub init_js {
-  SL::ClientJS->new;
-}
-
 sub init_p {
   SL::Presenter->get;
 }
@@ -438,7 +453,7 @@ sub build_tax_rows {
   my ($self) = @_;
 
   my $rows_as_html;
-  foreach my $tax (@{ $self->{taxes} }) {
+  foreach my $tax (sort { $a->{tax}->rate cmp $b->{tax}->rate } @{ $self->{taxes} }) {
     $rows_as_html .= $self->p->render('order/tabs/_tax_row', TAX => $tax, TAXINCLUDED => $self->order->taxincluded);
   }
   return $rows_as_html;
@@ -481,13 +496,34 @@ sub _recalc {
   pairwise { $a->{linetotal} = $b->{linetotal} } @{$self->order->items}, @{$pat{items}};
 }
 
-sub _save {
+
+sub _get_unalterable_data {
   my ($self) = @_;
 
-  # autovivify all cvars that are not in the form (cvars_by_config can do it)
   foreach my $item (@{ $self->order->items }) {
-    $item->cvars_by_config;
+    if ($item->id) {
+      # load data from orderitems (db)
+      my $db_item = SL::DB::OrderItem->new(id => $item->id)->load;
+      $item->$_($db_item->$_) for qw(active_discount_source active_price_source longdescription);
+    } else {
+      # set data from part (or other sources)
+      $item->longdescription($item->part->notes);
+      #$item->active_price_source('');
+      #$item->active_discount_source('');
+    }
+
+    # autovivify all cvars that are not in the form (cvars_by_config can do it).
+    # workaround to pre-parse number-cvars (parse_custom_variable_values does not parse number values).
+    foreach my $var (@{ $item->cvars_by_config }) {
+      $var->unparsed_value($::form->parse_amount(\%::myconfig, $var->{__unparsed_value})) if ($var->config->type eq 'number' && exists($var->{__unparsed_value}));
+    }
+    $item->parse_custom_variable_values;
   }
+}
+
+
+sub _save {
+  my ($self) = @_;
 
   my $errors = [];
   my $db = $self->order->db;
@@ -526,12 +562,14 @@ sub _create_pdf {
   my ($order, $pdf_ref, $params) = @_;
 
   my $print_form = Form->new('');
-  $print_form->{type}     = 'sales_order';
-  $print_form->{formname} = 'sales_order',
+  $print_form->{type}     = $order->type;
+  $print_form->{formname} = $order->type;
   $print_form->{format}   = $params->{format} || 'pdf',
   $print_form->{media}    = $params->{media}  || 'file';
 
   $order->flatten_to_form($print_form, format_amounts => 1);
+  # flatten_to_form sets payment_terms from customer/vendor - we do not want that here
+  delete $print_form->{payment_terms} if !$print_form->{payment_id};
 
   my @errors = ();
   $print_form->throw_on_error(sub {
@@ -563,3 +601,22 @@ sub _purchase_order_type {
 }
 
 1;
+
+__END__
+
+=encoding utf-8
+
+=head1 NAME
+
+SL::Controller::Order - controller for orders
+
+=head1 TODO
+
+Testing, PriceSources, pricefactor, units, currency, delivered, delivery order created, ...
+
+=head1 AUTHOR
+
+Bernd Bleßmann E<lt>bernd@kivitendo-premium.deE<gt>
+
+=cut
+