Revision 92edc424
Von Tamino Steinert vor fast 2 Jahren hinzugefügt
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
Workflow: order ↔ reclamation