Telefonnotizen Angebot/Auftrag
[kivitendo-erp.git] / SL / DB / Order.pm
index 8228def..fdaa1e8 100644 (file)
@@ -47,6 +47,16 @@ __PACKAGE__->meta->add_relationship(
     class                  => 'SL::DB::Exchangerate',
     column_map             => { currency_id => 'currency_id', transdate => 'transdate' },
   },
+  phone_notes => {
+    type         => 'one to many',
+    class        => 'SL::DB::Note',
+    column_map   => { id => 'trans_id' },
+    query_args   => [ trans_module => 'oe' ],
+    manager_args => {
+      with_objects => [ 'employee' ],
+      sort_by      => 'notes.itime',
+    }
+  },
 );
 
 SL::DB::Helper::Attr::make(__PACKAGE__, daily_exchangerate => 'numeric');
@@ -238,8 +248,23 @@ sub convert_to_invoice {
   my $invoice;
   if (!$self->db->with_transaction(sub {
     require SL::DB::Invoice;
-    $invoice = SL::DB::Invoice->new_from($self)->post(%params) || die;
+    $invoice = SL::DB::Invoice->new_from($self, %params)->post || die;
     $self->link_to_record($invoice);
+    # TODO extend link_to_record for items, otherwise long-term no d.r.y.
+    foreach my $item (@{ $invoice->items }) {
+      foreach (qw(orderitems)) {
+        if ($item->{"converted_from_${_}_id"}) {
+          die unless $item->{id};
+          RecordLinks->create_links('mode'       => 'ids',
+                                    'from_table' => $_,
+                                    'from_ids'   => $item->{"converted_from_${_}_id"},
+                                    'to_table'   => 'invoice',
+                                    'to_id'      => $item->{id},
+          ) || die;
+          delete $item->{"converted_from_${_}_id"};
+        }
+      }
+    }
     $self->update_attributes(closed => 1);
     1;
   })) {
@@ -275,7 +300,7 @@ sub convert_to_delivery_order {
       }
     }
 
-    $self->update_attributes(delivered => 1);
+    $self->update_attributes(delivered => 1) unless $::instance_conf->get_shipped_qty_require_stock_out;
     1;
   })) {
     return undef;
@@ -310,14 +335,13 @@ sub new_from {
     { from => 'purchase_order',    to => 'purchase_order',    abbr => 'popo' },
     { from => 'sales_order',       to => 'purchase_order',    abbr => 'sopo' },
     { from => 'purchase_order',    to => 'sales_order',       abbr => 'poso' },
+    { from => 'sales_order',       to => 'sales_quotation',   abbr => 'sosq' },
+    { from => 'purchase_order',    to => 'request_quotation', abbr => 'porq' },
   );
   my $from_to = (grep { $_->{from} eq $source->type && $_->{to} eq $destination_type} @from_tos)[0];
   croak("Cannot convert from '" . $source->type . "' to '" . $destination_type . "'") if !$from_to;
 
   my $is_abbr_any = sub {
-    # foreach my $abbr (@_) {
-    #   croak "no such abbreviation: '$abbr'" if !grep { $_->{abbr} eq $abbr } @from_tos;
-    # }
     any { $from_to->{abbr} eq $_ } @_;
   };
 
@@ -329,21 +353,21 @@ sub new_from {
   }
 
   my %args = ( map({ ( $_ => $source->$_ ) } qw(amount cp_id currency_id cusordnumber customer_id delivery_customer_id delivery_term_id delivery_vendor_id
-                                                department_id employee_id exchangerate globalproject_id intnotes marge_percent marge_total language_id netamount notes
+                                                department_id exchangerate globalproject_id intnotes marge_percent marge_total language_id netamount notes
                                                 ordnumber payment_id quonumber reqdate salesman_id shippingpoint shipvia taxincluded tax_point taxzone_id
-                                                transaction_description vendor_id
+                                                transaction_description vendor_id billing_address_id
                                              )),
                quotation => !!($destination_type =~ m{quotation$}),
                closed    => 0,
                delivered => 0,
                transdate => DateTime->today_local,
+               employee  => SL::DB::Manager::Employee->current,
             );
 
   if ( $is_abbr_any->(qw(sopo poso)) ) {
     $args{ordnumber} = undef;
     $args{quonumber} = undef;
     $args{reqdate}   = DateTime->today_local->next_workday();
-    $args{employee}  = SL::DB::Manager::Employee->current;
   }
   if ( $is_abbr_any->(qw(sopo)) ) {
     $args{customer_id}      = undef;
@@ -357,6 +381,11 @@ sub new_from {
   if ( $is_abbr_any->(qw(soso)) ) {
     $args{periodic_invoices_config} = $source->periodic_invoices_config->clone_and_reset if $source->periodic_invoices_config;
   }
+  if ( $is_abbr_any->(qw(sosq porq)) ) {
+    $args{ordnumber} = undef;
+    $args{quonumber} = undef;
+    $args{reqdate}   = DateTime->today_local->next_workday();
+  }
 
   # Custom shipto addresses (the ones specific to the sales/purchase
   # record and not to the customer/vendor) are only linked from
@@ -389,6 +418,7 @@ sub new_from {
                                                         marge_percent marge_price_factor marge_total
                                                         ordnumber parts_id price_factor price_factor_id pricegroup_id
                                                         project_id qty reqdate sellprice serialnumber ship subtotal transdate unit
+                                                        optional
                                                      )),
                                                  custom_variables => \@custom_variables,
     );
@@ -443,7 +473,7 @@ sub new_from_multi {
                        order_probability expected_billing_date)) {
     $attributes{$attr} = undef if any { ($sources->[0]->$attr//'') ne ($_->$attr//'') } @$sources;
   }
-  foreach my $attr (qw(cp_id currency_id employee_id salesman_id department_id
+  foreach my $attr (qw(cp_id currency_id salesman_id department_id
                        delivery_customer_id delivery_vendor_id shipto_id
                        globalproject_id exchangerate)) {
     $attributes{$attr} = undef if any { ($sources->[0]->$attr||0) != ($_->$attr||0) }   @$sources;
@@ -458,6 +488,9 @@ sub new_from_multi {
   # no periodic invoice config for new order
   $attributes{periodic_invoices_config} = undef;
 
+  # set emplyee to the current one
+  $attributes{employee} = SL::DB::Manager::Employee->current;
+
   # copy global ordnumber, transdate, cusordnumber into item scope
   #   unless already present there
   foreach my $attr (qw(ordnumber transdate cusordnumber)) {
@@ -593,7 +626,7 @@ L<SL::DB::Invoice::new_from>. That invoice is posted, and C<$self> is
 linked to the new invoice via L<SL::DB::RecordLink>. C<$self>'s
 C<closed> attribute is set to C<true>, and C<$self> is saved.
 
-The arguments in C<%params> are passed to L<SL::DB::Invoice::post>.
+The arguments in C<%params> are passed to L<SL::DB::Invoice::new_from>.
 
 Returns the new invoice instance on success and C<undef> on
 failure. The whole process is run inside a transaction. On failure