Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision c1808a62

Von Tamino Steinert vor fast 2 Jahren hinzugefügt

  • ID c1808a62515e52f14dd7ad04439d2c7623951eb2
  • Vorgänger 14b40469
  • Nachfolger 7ac17a23

Workflow: order ↔ reclamation

Unterschiede anzeigen:

SL/Controller/Order.pm
92 92
  );
93 93
}
94 94

  
95
sub action_add_from_reclamation {
96
  my ($self) = @_;
97

  
98
  require SL::DB::Reclamation;
99
  my $reclamation = SL::DB::Reclamation->new(id => $::form->{from_id})->load;
100
  my $order = $reclamation->convert_to_order();
101

  
102
  $self->order($order);
103

  
104
  $self->recalc();
105
  $self->pre_render();
106
  $self->render(
107
    'order/form',
108
    title => $self->get_title_for('edit'),
109
    %{$self->{template_args}}
110
  );
111
}
112

  
95 113
# edit an existing order
96 114
sub action_edit {
97 115
  my ($self) = @_;
......
791 809
  );
792 810
}
793 811

  
812
# save the order and redirect to the frontend subroutine for a new reclamation
813
sub action_save_and_reclamation {
814
  my ($self) = @_;
815

  
816
  # cann't use save_and_redirect_to, because id is set!
817
  my $errors = $self->save();
818
  if (scalar @{ $errors }) {
819
    $self->js->flash('error', $_) foreach @{ $errors };
820
    return $self->js->render();
821
  }
822

  
823
  my $to_type = $self->order->is_sales ? 'sales_reclamation'
824
                                       : 'purchase_reclamation';
825
  $self->redirect_to(
826
    controller => 'Reclamation',
827
    action     => 'add_from_order',
828
    type       => $to_type,
829
    from_id    => $self->order->id,
830
  );
831
}
832

  
794 833
# save the order and redirect to the frontend subroutine for a new
795 834
# invoice
796 835
sub action_save_and_invoice {
......
2339 2378
          only_if   => (any { $self->type eq $_ } (purchase_order_type())),
2340 2379
          disabled  => !$may_edit_create ? t8('You do not have the permissions to access this function.') : undef,
2341 2380
        ],
2381
        action => [
2382
          t8('Save and Reclamation'),
2383
          call      => [ 'kivi.Order.save', 'save_and_reclamation', $::instance_conf->get_order_warn_duplicate_parts ],
2384
          only_if   => (any { $self->type eq $_ } (sales_order_type(), purchase_order_type()))
2385
        ],
2342 2386
        action => [
2343 2387
          t8('Save and Invoice'),
2344 2388
          call      => [ 'kivi.Order.save', { action             => 'save_and_invoice',
SL/Controller/Reclamation.pm
68 68
                          save save_as_new print preview_pdf send_email
69 69
                          save_and_show_email_dialog
70 70
                          workflow_save_and_sales_or_purchase_reclamation
71
                          save_and_order
71 72
                       )]);
72 73

  
73 74
__PACKAGE__->run_before('get_unalterable_data',
......
75 76
                          save save_as_new print preview_pdf send_email
76 77
                          save_and_show_email_dialog
77 78
                          workflow_save_and_sales_or_purchase_reclamation
79
                          save_and_order
78 80
                        )]);
79 81

  
80 82
#
......
96 98
  );
97 99
}
98 100

  
101
sub action_add_from_order {
102
  my ($self) = @_;
103

  
104
  unless ($::form->{from_id}) {
105
    $self->js->flash('error', t8("Can't create new reclamation. No 'from_id' was given."));
106
    return $self->js->render();
107
  }
108

  
109
  require SL::DB::Order;
110
  my $order = SL::DB::Order->new(id => $::form->{from_id})->load;
111
  my $reclamation = $order->convert_to_reclamation();
112

  
113
  $self->reclamation($reclamation);
114

  
115
  $self->reinit_after_new_reclamation();
116

  
117
  $self->render(
118
    'reclamation/form',
119
    title => $self->get_title_for('add'),
120
    %{$self->{template_args}},
121
  );
122
}
123

  
99 124
# edit an existing reclamation
100 125
sub action_edit {
101 126
  my ($self) = @_;
......
467 492
  $self->redirect_to(@redirect_params);
468 493
}
469 494

  
495
sub action_save_and_order {
496
  my ($self) = @_;
497

  
498
  my $to_type = $self->reclamation->is_sales ? 'sales_order'
499
                                             : 'purchase_order';
500
  $self->save_and_redirect_to(
501
    controller => 'Order',
502
    action     => 'add_from_reclamation',
503
    type       => $to_type,
504
    from_id    => $self->reclamation->id,
505
  );
506
}
507

  
470 508
# workflow from purchase to sales reclamation
471 509
sub action_save_and_sales_reclamation {
472 510
  $_[0]->workflow_save_and_sales_or_purchase_reclamation();
......
1578 1616
  my ($self) = @_;
1579 1617
  my %allowed_linked_records = map {$_ => 1} qw(
1580 1618
    SL::DB::Reclamation
1619
    SL::DB::Order
1581 1620
  );
1582 1621
  my %allowed_linked_record_items = map {$_ => 1} qw(
1583 1622
    SL::DB::ReclamationItem
1623
    SL::DB::OrderItem
1584 1624
  );
1585 1625

  
1586 1626
  my $from_record_id = delete $::form->{converted_from_record_id};
......
2085 2125
          call      => [ 'kivi.Reclamation.purchase_reclamation_check_for_direct_delivery' ],
2086 2126
          only_if   => (any { $self->type eq $_ } (sales_reclamation_type())),
2087 2127
        ],
2128
        action => [
2129
          t8('Save and Order'),
2130
          call      => [
2131
            'kivi.Reclamation.save', 'save_and_order',
2132
            $::instance_conf->get_reclamation_warn_duplicate_parts,
2133
            $::instance_conf->get_reclamation_warn_no_reqdate,
2134
          ],
2135
        ],
2088 2136
      ], # end of combobox "Workflow"
2089 2137

  
2090 2138
      combobox => [
SL/DB/Order.pm
316 316
  return $delivery_order;
317 317
}
318 318

  
319
sub convert_to_reclamation {
320
  my ($self, %params) = @_;
321
  $params{destination_type} = $self->is_sales ? 'sales_reclamation'
322
                                              : 'purchase_reclamation';
323

  
324
  require SL::DB::Reclamation;
325
  my $reclamation = SL::DB::Reclamation->new_from($self, %params);
326

  
327
  return $reclamation;
328
}
329

  
319 330
sub _clone_orderitem_cvar {
320 331
  my ($cvar) = @_;
321 332

  
......
328 339
sub new_from {
329 340
  my ($class, $source, %params) = @_;
330 341

  
331
  croak("Unsupported source object type '" . ref($source) . "'") unless ref($source) eq 'SL::DB::Order';
342
  unless (any {ref($source) eq $_} qw(
343
    SL::DB::Order
344
    SL::DB::Reclamation
345
  )) {
346
    croak("Unsupported source object type '" . ref($source) . "'");
347
  }
332 348
  croak("A destination type must be given as parameter")         unless $params{destination_type};
333 349

  
334 350
  my $destination_type  = delete $params{destination_type};
......
348 364
    { from => 'request_quotation', to => 'sales_order',       abbr => 'rqso' },
349 365
    { from => 'sales_quotation',   to => 'request_quotation', abbr => 'sqrq' },
350 366
    { from => 'sales_order',       to => 'request_quotation', abbr => 'sorq' },
367
    { from => 'sales_reclamation', to => 'sales_order',       abbr => 'srso' },
368
    { from => 'purchase_reclamation', to => 'purchase_order', abbr => 'prpo' },
351 369
  );
352 370
  my $from_to = (grep { $_->{from} eq $source->type && $_->{to} eq $destination_type} @from_tos)[0];
353 371
  croak("Cannot convert from '" . $source->type . "' to '" . $destination_type . "'") if !$from_to;
......
361 379
  if (ref($source) eq 'SL::DB::Order') {
362 380
    $item_parent_id_column = 'trans_id';
363 381
    $item_parent_column    = 'order';
382
  } elsif ( ref($source) eq 'SL::DB::Reclamation') {
383
    $item_parent_id_column = 'reclamation_id';
384
    $item_parent_column    = 'reclamation';
364 385
  }
365 386

  
366
  my %args = ( map({ ( $_ => $source->$_ ) } qw(amount cp_id currency_id cusordnumber customer_id delivery_customer_id delivery_term_id delivery_vendor_id
367
                                                department_id exchangerate globalproject_id intnotes marge_percent marge_total language_id netamount notes
368
                                                ordnumber payment_id quonumber reqdate salesman_id shippingpoint shipvia taxincluded tax_point taxzone_id
369
                                                transaction_description vendor_id billing_address_id
370
                                             )),
371
               quotation => !!($destination_type =~ m{quotation$}),
372
               closed    => 0,
373
               delivered => 0,
374
               transdate => DateTime->today_local,
375
               employee  => SL::DB::Manager::Employee->current,
376
            );
377
  # reqdate in quotation is 'offer is valid    until reqdate'
378
  # reqdate in order     is 'will be delivered until reqdate'
379
  # both dates are setable (on|off)
380
  # and may have a additional interval in days (+ n days)
381
  # dies if this convention will change
382
  $args{reqdate} = $from_to->{to} =~ m/_quotation$/
383
                 ? $::instance_conf->get_reqdate_on
384
                 ? DateTime->today_local->next_workday(extra_days => $::instance_conf->get_reqdate_interval)->to_kivitendo
385
                 : undef
386
                 : $from_to->{to} =~ m/_order$/
387
                 ? $::instance_conf->get_deliverydate_on
388
                 ? DateTime->today_local->next_workday(extra_days => $::instance_conf->get_delivery_date_interval)->to_kivitendo
389
                 : undef
390
                 : die "Wrong state for reqdate";
387
  my %args;
388
  if (ref($source) eq 'SL::DB::Order') {
389
    %args = ( map({ ( $_ => $source->$_ ) } qw(amount cp_id currency_id cusordnumber customer_id delivery_customer_id delivery_term_id delivery_vendor_id
390
                                               department_id exchangerate globalproject_id intnotes marge_percent marge_total language_id netamount notes
391
                                               ordnumber payment_id quonumber reqdate salesman_id shippingpoint shipvia taxincluded tax_point taxzone_id
392
                                               transaction_description vendor_id billing_address_id
393
                                            )),
394
                 quotation => !!($destination_type =~ m{quotation$}),
395
                 closed    => 0,
396
                 delivered => 0,
397
                 transdate => DateTime->today_local,
398
                 employee  => SL::DB::Manager::Employee->current,
399
              );
400
    # reqdate in quotation is 'offer is valid    until reqdate'
401
    # reqdate in order     is 'will be delivered until reqdate'
402
    # both dates are setable (on|off)
403
    # and may have a additional interval in days (+ n days)
404
    # dies if this convention will change
405
    $args{reqdate} = $from_to->{to} =~ m/_quotation$/
406
                   ? $::instance_conf->get_reqdate_on
407
                   ? DateTime->today_local->next_workday(extra_days => $::instance_conf->get_reqdate_interval)->to_kivitendo
408
                   : undef
409
                   : $from_to->{to} =~ m/_order$/
410
                   ? $::instance_conf->get_deliverydate_on
411
                   ? DateTime->today_local->next_workday(extra_days => $::instance_conf->get_delivery_date_interval)->to_kivitendo
412
                   : undef
413
                   : die "Wrong state for reqdate";
414
  } elsif ( ref($source) eq 'SL::DB::Reclamation') {
415
    #TODO(Tamino): add billing_address_id to reclamation
416
    %args = ( map({ ( $_ => $source->$_ ) } qw(
417
        amount currency_id customer_id delivery_term_id department_id
418
        exchangerate globalproject_id intnotes language_id netamount
419
        notes payment_id  reqdate salesman_id shippingpoint shipvia taxincluded
420
        tax_point taxzone_id transaction_description vendor_id
421
      )),
422
      cp_id     => $source->{contact_id},
423
      closed    => 0,
424
      delivered => 0,
425
      transdate => DateTime->today_local,
426
      employee  => SL::DB::Manager::Employee->current,
427
   );
428
  }
391 429

  
392 430
  if ( $is_abbr_any->(qw(sopo poso rqso sosq porq rqsq sqrq sorq)) ) {
393 431
    $args{ordnumber} = undef;
......
434 472
    $item_parents{$source_item_id} ||= $source_item->$item_parent_column;
435 473
    my $item_parent                  = $item_parents{$source_item_id};
436 474

  
437
    my $current_oe_item = SL::DB::OrderItem->new(map({ ( $_ => $source_item->$_ ) }
438
                                                     qw(active_discount_source active_price_source base_qty cusordnumber
439
                                                        description discount lastcost longdescription
440
                                                        marge_percent marge_price_factor marge_total
441
                                                        ordnumber parts_id price_factor price_factor_id pricegroup_id
442
                                                        project_id qty reqdate sellprice serialnumber ship subtotal transdate unit
443
                                                        optional
444
                                                     )),
445
                                                 custom_variables => \@custom_variables,
446
    );
475
    my $current_oe_item;
476
    if (ref($source) eq 'SL::DB::Order') {
477
      $current_oe_item = SL::DB::OrderItem->new(map({ ( $_ => $source_item->$_ ) }
478
                                                       qw(active_discount_source active_price_source base_qty cusordnumber
479
                                                          description discount lastcost longdescription
480
                                                          marge_percent marge_price_factor marge_total
481
                                                          ordnumber parts_id price_factor price_factor_id pricegroup_id
482
                                                          project_id qty reqdate sellprice serialnumber ship subtotal transdate unit
483
                                                          optional
484
                                                       )),
485
                                                   custom_variables => \@custom_variables,
486
      );
487
    } elsif (ref($source) eq 'SL::DB::Reclamation') {
488
      $current_oe_item = SL::DB::OrderItem->new(
489
        map({ ( $_ => $source_item->$_ ) } qw(
490
          active_discount_source active_price_source base_qty description
491
          discount lastcost longdescription parts_id price_factor
492
          price_factor_id pricegroup_id project_id qty reqdate sellprice
493
          serialnumber unit
494
        )),
495
        custom_variables => \@custom_variables,
496
      );
497
    }
447 498
    if ( $is_abbr_any->(qw(sopo)) ) {
448 499
      $current_oe_item->sellprice($source_item->lastcost);
449 500
      $current_oe_item->discount(0);
......
452 503
      $current_oe_item->lastcost($source_item->sellprice);
453 504
    }
454 505
    $current_oe_item->{"converted_from_orderitems_id"} = $_->{id} if ref($item_parent) eq 'SL::DB::Order';
506
    $current_oe_item->{"converted_from_reclamation_item_id"} = $_->{id} if ref($item_parent) eq 'SL::DB::Reclamation';
455 507
    $current_oe_item;
456 508
  } @{ $items };
457 509

  
SL/DB/Reclamation.pm
181 181
      where => [  $valid_for_type => 1 ]);
182 182
}
183 183

  
184
sub convert_to_order {
185
  my ($self, %params) = @_;
186

  
187
  my $order;
188
  $params{destination_type} = $self->is_sales ? 'sales_order'
189
                                              : 'purchase_order';
190
  if (!$self->db->with_transaction(sub {
191
    require SL::DB::Order;
192
    $order = SL::DB::Order->new_from($self, %params);
193
    $order->save;
194
    $self->link_to_record($order);
195
    foreach my $item (@{ $order->items }) {
196
      foreach (qw(reclamation_item)) {
197
        if ($item->{"converted_from_${_}_id"}) {
198
          die unless $item->{id};
199
          RecordLinks->create_links('dbh'        => $self->db->dbh,
200
                                    'mode'       => 'ids',
201
                                    'from_table' => 'reclamation_items',
202
                                    'from_ids'   => $item->{"converted_from_${_}_id"},
203
                                    'to_table'   => 'orderitems',
204
                                    'to_id'      => $item->{id},
205
          ) || die;
206
          delete $item->{"converted_from_${_}_id"};
207
        }
208
      }
209
    }
210

  
211
    1;
212
  })) {
213
    return undef;
214
  }
215

  
216
  return $order;
217
}
218

  
184 219
#TODO(Werner): überprüfen ob alle Felder richtig gestetzt werden
185 220
sub new_from {
186 221
  my ($class, $source, %params) = @_;
187 222
  my %allowed_sources = map { $_ => 1 } qw(
188 223
    SL::DB::Reclamation
224
    SL::DB::Order
189 225
  );
190 226
  unless( $allowed_sources{ref $source} ) {
191 227
    croak("Unsupported source object type '" . ref($source) . "'");
......
200 236
    { from => 'purchase_reclamation',    to => 'purchase_reclamation', abbr => 'prpr', },
201 237
    { from => 'sales_reclamation',       to => 'purchase_reclamation', abbr => 'srpr', },
202 238
    { from => 'purchase_reclamation',    to => 'sales_reclamation',    abbr => 'prsr', },
239
    #Order
240
    { from => 'sales_order',             to => 'sales_reclamation',    abbr => 'sosr', },
241
    { from => 'purchase_order',          to => 'purchase_reclamation', abbr => 'popr', },
203 242
  );
204 243
  my $from_to = (grep { $_->{from} eq $source->type && $_->{to} eq $destination_type} @from_tos)[0];
205 244
  if (!$from_to) {
......
244 283
      transaction_description
245 284
      vendor_id
246 285
    ); # }}} for vim folds
286
  } elsif ( $is_abbr_any->(qw(sosr popr)) ) { #Order
287
    map { $record_args{$_} = $source->$_ } # {{{ for vim folds
288
    qw(
289
      amount
290
      currency_id
291
      customer_id
292
      delivery_term_id
293
      department_id
294
      exchangerate
295
      globalproject_id
296
      intnotes
297
      language_id
298
      netamount
299
      notes
300
      payment_id
301
      salesman_id
302
      shippingpoint
303
      shipvia
304
      tax_point
305
      taxincluded
306
      taxzone_id
307
      transaction_description
308
      vendor_id
309
    );
310
    $record_args{contact_id} = $source->cp_id;
311
    $record_args{cv_record_number} = $source->cusordnumber;
312
    # }}} for vim folds
247 313
  }
248 314

  
249 315
  if ( ($from_to->{from} =~ m{sales}) && ($from_to->{to} =~ m{purchase}) ) {
SL/DB/ReclamationItem.pm
53 53
  unless (any {ref($source) eq $_}
54 54
    qw(
55 55
      SL::DB::ReclamationItem
56
      SL::DB::OrderItem
56 57
    )
57 58
  ) {
58 59
    croak("Unsupported source object type '" . ref($source) . "'");
......
70 71
      unit
71 72
    );
72 73
    $item_args{custom_variables} = \@custom_variables;
74
  } elsif (ref($source) eq 'SL::DB::OrderItem') {
75
    map { $item_args{$_} = $source->$_ } qw(
76
      active_discount_source active_price_source base_qty description discount
77
      lastcost longdescription parts_id position price_factor price_factor_id
78
      pricegroup_id project_id qty reqdate sellprice serialnumber unit
79
    );
80
    $item_args{custom_variables} = \@custom_variables;
73 81
  }
74 82

  
75 83
  my $item = $class->new(%item_args);

Auch abrufbar als: Unified diff