Revision 1d242038
Von Bernd Bleßmann vor mehr als 6 Jahren hinzugefügt
SL/Controller/Order.pm | ||
---|---|---|
39 | 39 |
|
40 | 40 |
|
41 | 41 |
# safety |
42 |
__PACKAGE__->run_before('_check_auth');
|
|
42 |
__PACKAGE__->run_before('check_auth'); |
|
43 | 43 |
|
44 |
__PACKAGE__->run_before('_recalc',
|
|
44 |
__PACKAGE__->run_before('recalc', |
|
45 | 45 |
only => [ qw(save save_as_new save_and_delivery_order save_and_invoice print create_pdf send_email) ]); |
46 | 46 |
|
47 |
__PACKAGE__->run_before('_get_unalterable_data',
|
|
47 |
__PACKAGE__->run_before('get_unalterable_data', |
|
48 | 48 |
only => [ qw(save save_as_new save_and_delivery_order save_and_invoice print create_pdf send_email) ]); |
49 | 49 |
|
50 | 50 |
# |
... | ... | |
56 | 56 |
my ($self) = @_; |
57 | 57 |
|
58 | 58 |
$self->order->transdate(DateTime->now_local()); |
59 |
my $extra_days = $self->type eq _sales_quotation_type() ? $::instance_conf->get_reqdate_interval : 1;
|
|
59 |
my $extra_days = $self->type eq sales_quotation_type() ? $::instance_conf->get_reqdate_interval : 1; |
|
60 | 60 |
$self->order->reqdate(DateTime->today_local->next_workday(extra_days => $extra_days)) if !$self->order->reqdate; |
61 | 61 |
|
62 |
$self->_pre_render();
|
|
62 |
$self->pre_render(); |
|
63 | 63 |
$self->render( |
64 | 64 |
'order/form', |
65 |
title => $self->_get_title_for('add'),
|
|
65 |
title => $self->get_title_for('add'), |
|
66 | 66 |
%{$self->{template_args}} |
67 | 67 |
); |
68 | 68 |
} |
... | ... | |
71 | 71 |
sub action_edit { |
72 | 72 |
my ($self) = @_; |
73 | 73 |
|
74 |
$self->_load_order;
|
|
75 |
$self->_recalc();
|
|
76 |
$self->_pre_render();
|
|
74 |
$self->load_order; |
|
75 |
$self->recalc(); |
|
76 |
$self->pre_render(); |
|
77 | 77 |
$self->render( |
78 | 78 |
'order/form', |
79 |
title => $self->_get_title_for('edit'),
|
|
79 |
title => $self->get_title_for('edit'), |
|
80 | 80 |
%{$self->{template_args}} |
81 | 81 |
); |
82 | 82 |
} |
... | ... | |
85 | 85 |
sub action_delete { |
86 | 86 |
my ($self) = @_; |
87 | 87 |
|
88 |
my $errors = $self->_delete();
|
|
88 |
my $errors = $self->delete(); |
|
89 | 89 |
|
90 | 90 |
if (scalar @{ $errors }) { |
91 | 91 |
$self->js->flash('error', $_) foreach @{ $errors }; |
92 | 92 |
return $self->js->render(); |
93 | 93 |
} |
94 | 94 |
|
95 |
my $text = $self->type eq _sales_order_type() ? $::locale->text('The order has been deleted')
|
|
96 |
: $self->type eq _purchase_order_type() ? $::locale->text('The order has been deleted')
|
|
97 |
: $self->type eq _sales_quotation_type() ? $::locale->text('The quotation has been deleted')
|
|
98 |
: $self->type eq _request_quotation_type() ? $::locale->text('The rfq has been deleted')
|
|
95 |
my $text = $self->type eq sales_order_type() ? $::locale->text('The order has been deleted') |
|
96 |
: $self->type eq purchase_order_type() ? $::locale->text('The order has been deleted') |
|
97 |
: $self->type eq sales_quotation_type() ? $::locale->text('The quotation has been deleted') |
|
98 |
: $self->type eq request_quotation_type() ? $::locale->text('The rfq has been deleted') |
|
99 | 99 |
: ''; |
100 | 100 |
flash_later('info', $text); |
101 | 101 |
|
... | ... | |
111 | 111 |
sub action_save { |
112 | 112 |
my ($self) = @_; |
113 | 113 |
|
114 |
my $errors = $self->_save();
|
|
114 |
my $errors = $self->save(); |
|
115 | 115 |
|
116 | 116 |
if (scalar @{ $errors }) { |
117 | 117 |
$self->js->flash('error', $_) foreach @{ $errors }; |
118 | 118 |
return $self->js->render(); |
119 | 119 |
} |
120 | 120 |
|
121 |
my $text = $self->type eq _sales_order_type() ? $::locale->text('The order has been saved')
|
|
122 |
: $self->type eq _purchase_order_type() ? $::locale->text('The order has been saved')
|
|
123 |
: $self->type eq _sales_quotation_type() ? $::locale->text('The quotation has been saved')
|
|
124 |
: $self->type eq _request_quotation_type() ? $::locale->text('The rfq has been saved')
|
|
121 |
my $text = $self->type eq sales_order_type() ? $::locale->text('The order has been saved') |
|
122 |
: $self->type eq purchase_order_type() ? $::locale->text('The order has been saved') |
|
123 |
: $self->type eq sales_quotation_type() ? $::locale->text('The quotation has been saved') |
|
124 |
: $self->type eq request_quotation_type() ? $::locale->text('The rfq has been saved') |
|
125 | 125 |
: ''; |
126 | 126 |
flash_later('info', $text); |
127 | 127 |
|
... | ... | |
162 | 162 |
|
163 | 163 |
# Set new reqdate unless changed |
164 | 164 |
if ($order->reqdate == $saved_order->reqdate) { |
165 |
my $extra_days = $self->type eq _sales_quotation_type() ? $::instance_conf->get_reqdate_interval : 1;
|
|
165 |
my $extra_days = $self->type eq sales_quotation_type() ? $::instance_conf->get_reqdate_interval : 1; |
|
166 | 166 |
$new_attrs{reqdate} = DateTime->today_local->next_workday(extra_days => $extra_days); |
167 | 167 |
} else { |
168 | 168 |
$new_attrs{reqdate} = $order->reqdate; |
... | ... | |
213 | 213 |
|
214 | 214 |
# create a form for generate_attachment_filename |
215 | 215 |
my $form = Form->new; |
216 |
$form->{$self->_nr_key()} = $self->order->number;
|
|
216 |
$form->{$self->nr_key()} = $self->order->number;
|
|
217 | 217 |
$form->{type} = $self->type; |
218 | 218 |
$form->{format} = $format; |
219 | 219 |
$form->{formname} = $formname; |
... | ... | |
221 | 221 |
my $pdf_filename = $form->generate_attachment_filename(); |
222 | 222 |
|
223 | 223 |
my $pdf; |
224 |
my @errors = _create_pdf($self->order, \$pdf, { format => $format,
|
|
225 |
formname => $formname, |
|
226 |
language => $language, |
|
227 |
groupitems => $groupitems }); |
|
224 |
my @errors = generate_pdf($self->order, \$pdf, { format => $format,
|
|
225 |
formname => $formname,
|
|
226 |
language => $language,
|
|
227 |
groupitems => $groupitems });
|
|
228 | 228 |
if (scalar @errors) { |
229 | 229 |
return $self->js->flash('error', t8('Conversion to PDF failed: #1', $errors[0]))->render; |
230 | 230 |
} |
... | ... | |
321 | 321 |
# Todo: get addresses from shipto, if any |
322 | 322 |
|
323 | 323 |
my $form = Form->new; |
324 |
$form->{$self->_nr_key()} = $self->order->number;
|
|
324 |
$form->{$self->nr_key()} = $self->order->number;
|
|
325 | 325 |
$form->{formname} = $self->type; |
326 | 326 |
$form->{type} = $self->type; |
327 | 327 |
$form->{language} = 'de'; |
... | ... | |
332 | 332 |
$email_form->{message} = $form->generate_email_body(); |
333 | 333 |
$email_form->{js_send_function} = 'kivi.Order.send_email()'; |
334 | 334 |
|
335 |
my %files = $self->_get_files_for_email_dialog();
|
|
335 |
my %files = $self->get_files_for_email_dialog(); |
|
336 | 336 |
my $dialog_html = $self->render('common/_send_email_dialog', { output => 0 }, |
337 | 337 |
email_form => $email_form, |
338 | 338 |
show_bcc => $::auth->assert('email_bcc', 'may fail'), |
... | ... | |
369 | 369 |
$language = SL::DB::Language->new(id => $::form->{print_options}->{language_id})->load if $::form->{print_options}->{language_id}; |
370 | 370 |
|
371 | 371 |
my $pdf; |
372 |
my @errors = _create_pdf($self->order, \$pdf, {media => $::form->{media},
|
|
373 |
format => $::form->{print_options}->{format}, |
|
374 |
formname => $::form->{print_options}->{formname}, |
|
375 |
language => $language, |
|
376 |
groupitems => $::form->{print_options}->{groupitems}}); |
|
372 |
my @errors = genereate_pdf($self->order, \$pdf, {media => $::form->{media},
|
|
373 |
format => $::form->{print_options}->{format},
|
|
374 |
formname => $::form->{print_options}->{formname},
|
|
375 |
language => $language,
|
|
376 |
groupitems => $::form->{print_options}->{groupitems}});
|
|
377 | 377 |
if (scalar @errors) { |
378 | 378 |
return $self->js->flash('error', t8('Conversion to PDF failed: #1', $errors[0]))->render($self); |
379 | 379 |
} |
... | ... | |
413 | 413 |
sub action_show_periodic_invoices_config_dialog { |
414 | 414 |
my ($self) = @_; |
415 | 415 |
|
416 |
my $config = _make_periodic_invoices_config_from_yaml(delete $::form->{config});
|
|
416 |
my $config = make_periodic_invoices_config_from_yaml(delete $::form->{config}); |
|
417 | 417 |
$config ||= SL::DB::Manager::PeriodicInvoicesConfig->find_by(oe_id => $::form->{id}) if $::form->{id}; |
418 | 418 |
$config ||= SL::DB::PeriodicInvoicesConfig->new(periodicity => 'm', |
419 | 419 |
order_value_periodicity => 'p', # = same as periodicity |
... | ... | |
478 | 478 |
|
479 | 479 |
my $periodic_invoices_config = YAML::Dump($config); |
480 | 480 |
|
481 |
my $status = $self->_get_periodic_invoices_status($config);
|
|
481 |
my $status = $self->get_periodic_invoices_status($config); |
|
482 | 482 |
|
483 | 483 |
$self->js |
484 | 484 |
->remove('#order_periodic_invoices_config') |
... | ... | |
492 | 492 |
sub action_get_has_active_periodic_invoices { |
493 | 493 |
my ($self) = @_; |
494 | 494 |
|
495 |
my $config = _make_periodic_invoices_config_from_yaml(delete $::form->{config});
|
|
495 |
my $config = make_periodic_invoices_config_from_yaml(delete $::form->{config}); |
|
496 | 496 |
$config ||= SL::DB::Manager::PeriodicInvoicesConfig->find_by(oe_id => $::form->{id}) if $::form->{id}; |
497 | 497 |
|
498 | 498 |
my $has_active_periodic_invoices = |
499 |
$self->type eq _sales_order_type()
|
|
499 |
$self->type eq sales_order_type() |
|
500 | 500 |
&& $config |
501 | 501 |
&& $config->active |
502 | 502 |
&& (!$config->end_date || ($config->end_date > DateTime->today_local)) |
... | ... | |
510 | 510 |
sub action_save_and_delivery_order { |
511 | 511 |
my ($self) = @_; |
512 | 512 |
|
513 |
my $errors = $self->_save();
|
|
513 |
my $errors = $self->save(); |
|
514 | 514 |
|
515 | 515 |
if (scalar @{ $errors }) { |
516 | 516 |
$self->js->flash('error', $_) foreach @{ $errors }; |
517 | 517 |
return $self->js->render(); |
518 | 518 |
} |
519 | 519 |
|
520 |
my $text = $self->type eq _sales_order_type() ? $::locale->text('The order has been saved')
|
|
521 |
: $self->type eq _purchase_order_type() ? $::locale->text('The order has been saved')
|
|
522 |
: $self->type eq _sales_quotation_type() ? $::locale->text('The quotation has been saved')
|
|
523 |
: $self->type eq _request_quotation_type() ? $::locale->text('The rfq has been saved')
|
|
520 |
my $text = $self->type eq sales_order_type() ? $::locale->text('The order has been saved') |
|
521 |
: $self->type eq purchase_order_type() ? $::locale->text('The order has been saved') |
|
522 |
: $self->type eq sales_quotation_type() ? $::locale->text('The quotation has been saved') |
|
523 |
: $self->type eq request_quotation_type() ? $::locale->text('The rfq has been saved') |
|
524 | 524 |
: ''; |
525 | 525 |
flash_later('info', $text); |
526 | 526 |
|
... | ... | |
538 | 538 |
sub action_save_and_invoice { |
539 | 539 |
my ($self) = @_; |
540 | 540 |
|
541 |
my $errors = $self->_save();
|
|
541 |
my $errors = $self->save(); |
|
542 | 542 |
|
543 | 543 |
if (scalar @{ $errors }) { |
544 | 544 |
$self->js->flash('error', $_) foreach @{ $errors }; |
545 | 545 |
return $self->js->render(); |
546 | 546 |
} |
547 | 547 |
|
548 |
my $text = $self->type eq _sales_order_type() ? $::locale->text('The order has been saved')
|
|
549 |
: $self->type eq _purchase_order_type() ? $::locale->text('The order has been saved')
|
|
550 |
: $self->type eq _sales_quotation_type() ? $::locale->text('The quotation has been saved')
|
|
551 |
: $self->type eq _request_quotation_type() ? $::locale->text('The rfq has been saved')
|
|
548 |
my $text = $self->type eq sales_order_type() ? $::locale->text('The order has been saved') |
|
549 |
: $self->type eq purchase_order_type() ? $::locale->text('The order has been saved') |
|
550 |
: $self->type eq sales_quotation_type() ? $::locale->text('The quotation has been saved') |
|
551 |
: $self->type eq request_quotation_type() ? $::locale->text('The rfq has been saved') |
|
552 | 552 |
: ''; |
553 | 553 |
flash_later('info', $text); |
554 | 554 |
|
... | ... | |
563 | 563 |
|
564 | 564 |
# workflow from sales quotation to sales order |
565 | 565 |
sub action_sales_order { |
566 |
$_[0]->_workflow_sales_or_purchase_order();
|
|
566 |
$_[0]->workflow_sales_or_purchase_order(); |
|
567 | 567 |
} |
568 | 568 |
|
569 | 569 |
# workflow from rfq to purchase order |
570 | 570 |
sub action_purchase_order { |
571 |
$_[0]->_workflow_sales_or_purchase_order();
|
|
571 |
$_[0]->workflow_sales_or_purchase_order(); |
|
572 | 572 |
} |
573 | 573 |
|
574 | 574 |
# set form elements in respect to a changed customer or vendor |
... | ... | |
577 | 577 |
sub action_customer_vendor_changed { |
578 | 578 |
my ($self) = @_; |
579 | 579 |
|
580 |
_setup_order_from_cv($self->order);
|
|
581 |
$self->_recalc();
|
|
580 |
setup_order_from_cv($self->order); |
|
581 |
$self->recalc(); |
|
582 | 582 |
|
583 | 583 |
my $cv_method = $self->cv; |
584 | 584 |
|
... | ... | |
607 | 607 |
->val( '#order_intnotes', $self->order->intnotes) |
608 | 608 |
->focus( '#order_' . $self->cv . '_id'); |
609 | 609 |
|
610 |
$self->_js_redisplay_amounts_and_taxes;
|
|
610 |
$self->js_redisplay_amounts_and_taxes; |
|
611 | 611 |
$self->js->render(); |
612 | 612 |
} |
613 | 613 |
|
... | ... | |
655 | 655 |
my $old_unit_obj = SL::DB::Unit->new(name => $::form->{old_unit})->load; |
656 | 656 |
$item->sellprice($item->unit_obj->convert_to($item->sellprice, $old_unit_obj)); |
657 | 657 |
|
658 |
$self->_recalc();
|
|
658 |
$self->recalc(); |
|
659 | 659 |
|
660 | 660 |
$self->js |
661 | 661 |
->run('kivi.Order.update_sellprice', $::form->{item_id}, $item->sellprice_as_number); |
662 |
$self->_js_redisplay_line_values;
|
|
663 |
$self->_js_redisplay_amounts_and_taxes;
|
|
662 |
$self->js_redisplay_line_values; |
|
663 |
$self->js_redisplay_amounts_and_taxes; |
|
664 | 664 |
$self->js->render(); |
665 | 665 |
} |
666 | 666 |
|
... | ... | |
672 | 672 |
|
673 | 673 |
return unless $form_attr->{parts_id}; |
674 | 674 |
|
675 |
my $item = _new_item($self->order, $form_attr);
|
|
675 |
my $item = new_item($self->order, $form_attr); |
|
676 | 676 |
|
677 | 677 |
$self->order->add_items($item); |
678 | 678 |
|
679 |
$self->_recalc();
|
|
679 |
$self->recalc(); |
|
680 | 680 |
|
681 | 681 |
my $item_id = join('_', 'new', Time::HiRes::gettimeofday(), int rand 1000000000000); |
682 | 682 |
my $row_as_html = $self->p->render('order/tabs/_row', |
... | ... | |
697 | 697 |
unit => $assortment_item->unit, |
698 | 698 |
description => $assortment_item->part->description, |
699 | 699 |
}; |
700 |
my $item = _new_item($self->order, $attr);
|
|
700 |
my $item = new_item($self->order, $attr); |
|
701 | 701 |
|
702 | 702 |
# set discount to 100% if item isn't supposed to be charged, overwriting any customer discount |
703 | 703 |
$item->discount(1) unless $assortment_item->charge; |
704 | 704 |
|
705 | 705 |
$self->order->add_items( $item ); |
706 |
$self->_recalc();
|
|
706 |
$self->recalc(); |
|
707 | 707 |
my $item_id = join('_', 'new', Time::HiRes::gettimeofday(), int rand 1000000000000); |
708 | 708 |
my $row_as_html = $self->p->render('order/tabs/_row', |
709 | 709 |
ITEM => $item, |
... | ... | |
723 | 723 |
->run('kivi.Order.renumber_positions') |
724 | 724 |
->focus('#add_item_parts_id_name'); |
725 | 725 |
|
726 |
$self->_js_redisplay_amounts_and_taxes;
|
|
726 |
$self->js_redisplay_amounts_and_taxes; |
|
727 | 727 |
$self->js->render(); |
728 | 728 |
} |
729 | 729 |
|
... | ... | |
764 | 764 |
|
765 | 765 |
my @items; |
766 | 766 |
foreach my $attr (@form_attr) { |
767 |
my $item = _new_item($self->order, $attr);
|
|
767 |
my $item = new_item($self->order, $attr); |
|
768 | 768 |
push @items, $item; |
769 | 769 |
if ( $item->part->is_assortment ) { |
770 | 770 |
foreach my $assortment_item ( @{$item->part->assortment_items} ) { |
... | ... | |
773 | 773 |
unit => $assortment_item->unit, |
774 | 774 |
description => $assortment_item->part->description, |
775 | 775 |
}; |
776 |
my $item = _new_item($self->order, $attr);
|
|
776 |
my $item = new_item($self->order, $attr); |
|
777 | 777 |
|
778 | 778 |
# set discount to 100% if item isn't supposed to be charged, overwriting any customer discount |
779 | 779 |
$item->discount(1) unless $assortment_item->charge; |
... | ... | |
783 | 783 |
} |
784 | 784 |
$self->order->add_items(@items); |
785 | 785 |
|
786 |
$self->_recalc();
|
|
786 |
$self->recalc(); |
|
787 | 787 |
|
788 | 788 |
foreach my $item (@items) { |
789 | 789 |
my $item_id = join('_', 'new', Time::HiRes::gettimeofday(), int rand 1000000000000); |
... | ... | |
804 | 804 |
->run('kivi.Order.renumber_positions') |
805 | 805 |
->focus('#add_item_parts_id_name'); |
806 | 806 |
|
807 |
$self->_js_redisplay_amounts_and_taxes;
|
|
807 |
$self->js_redisplay_amounts_and_taxes; |
|
808 | 808 |
$self->js->render(); |
809 | 809 |
} |
810 | 810 |
|
... | ... | |
812 | 812 |
sub action_recalc_amounts_and_taxes { |
813 | 813 |
my ($self) = @_; |
814 | 814 |
|
815 |
$self->_recalc();
|
|
815 |
$self->recalc(); |
|
816 | 816 |
|
817 |
$self->_js_redisplay_line_values;
|
|
818 |
$self->_js_redisplay_amounts_and_taxes;
|
|
817 |
$self->js_redisplay_line_values; |
|
818 |
$self->js_redisplay_amounts_and_taxes; |
|
819 | 819 |
$self->js->render(); |
820 | 820 |
} |
821 | 821 |
|
... | ... | |
876 | 876 |
sub action_load_second_rows { |
877 | 877 |
my ($self) = @_; |
878 | 878 |
|
879 |
$self->_recalc() if $self->order->is_sales; # for margin calculation
|
|
879 |
$self->recalc() if $self->order->is_sales; # for margin calculation |
|
880 | 880 |
|
881 | 881 |
foreach my $item_id (@{ $::form->{item_ids} }) { |
882 | 882 |
my $idx = first_index { $_ eq $item_id } @{ $::form->{orderitem_ids} }; |
883 | 883 |
my $item = $self->order->items_sorted->[$idx]; |
884 | 884 |
|
885 |
$self->_js_load_second_row($item, $item_id, 0);
|
|
885 |
$self->js_load_second_row($item, $item_id, 0); |
|
886 | 886 |
} |
887 | 887 |
|
888 | 888 |
$self->js->run('kivi.Order.init_row_handlers') if $self->order->is_sales; # for lastcosts change-callback |
... | ... | |
890 | 890 |
$self->js->render(); |
891 | 891 |
} |
892 | 892 |
|
893 |
sub _js_load_second_row {
|
|
893 |
sub js_load_second_row { |
|
894 | 894 |
my ($self, $item, $item_id, $do_parse) = @_; |
895 | 895 |
|
896 | 896 |
if ($do_parse) { |
... | ... | |
910 | 910 |
->data('.row_entry:has(#item_' . $item_id . ') [name = "second_row"]', 'loaded', 1); |
911 | 911 |
} |
912 | 912 |
|
913 |
sub _js_redisplay_line_values {
|
|
913 |
sub js_redisplay_line_values { |
|
914 | 914 |
my ($self) = @_; |
915 | 915 |
|
916 | 916 |
my $is_sales = $self->order->is_sales; |
... | ... | |
935 | 935 |
->run('kivi.Order.redisplay_line_values', $is_sales, \@data); |
936 | 936 |
} |
937 | 937 |
|
938 |
sub _js_redisplay_amounts_and_taxes {
|
|
938 |
sub js_redisplay_amounts_and_taxes { |
|
939 | 939 |
my ($self) = @_; |
940 | 940 |
|
941 | 941 |
if (scalar @{ $self->{taxes} }) { |
... | ... | |
962 | 962 |
# |
963 | 963 |
|
964 | 964 |
sub init_valid_types { |
965 |
[ _sales_order_type(), _purchase_order_type(), _sales_quotation_type(), _request_quotation_type() ];
|
|
965 |
[ sales_order_type(), purchase_order_type(), sales_quotation_type(), request_quotation_type() ];
|
|
966 | 966 |
} |
967 | 967 |
|
968 | 968 |
sub init_type { |
... | ... | |
978 | 978 |
sub init_cv { |
979 | 979 |
my ($self) = @_; |
980 | 980 |
|
981 |
my $cv = (any { $self->type eq $_ } (_sales_order_type(), _sales_quotation_type())) ? 'customer'
|
|
982 |
: (any { $self->type eq $_ } (_purchase_order_type(), _request_quotation_type())) ? 'vendor'
|
|
981 |
my $cv = (any { $self->type eq $_ } (sales_order_type(), sales_quotation_type())) ? 'customer'
|
|
982 |
: (any { $self->type eq $_ } (purchase_order_type(), request_quotation_type())) ? 'vendor'
|
|
983 | 983 |
: die "Not a valid type for order"; |
984 | 984 |
|
985 | 985 |
return $cv; |
... | ... | |
990 | 990 |
} |
991 | 991 |
|
992 | 992 |
sub init_order { |
993 |
$_[0]->_make_order;
|
|
993 |
$_[0]->make_order; |
|
994 | 994 |
} |
995 | 995 |
|
996 | 996 |
# model used to filter/display the parts in the multi-items dialog |
... | ... | |
1015 | 1015 |
SL::DB::Manager::PriceFactor->get_all; |
1016 | 1016 |
} |
1017 | 1017 |
|
1018 |
sub _check_auth {
|
|
1018 |
sub check_auth { |
|
1019 | 1019 |
my ($self) = @_; |
1020 | 1020 |
|
1021 | 1021 |
my $right_for = { map { $_ => $_.'_edit' } @{$self->valid_types} }; |
... | ... | |
1099 | 1099 |
$self->js->render; |
1100 | 1100 |
} |
1101 | 1101 |
|
1102 |
sub _load_order {
|
|
1102 |
sub load_order { |
|
1103 | 1103 |
my ($self) = @_; |
1104 | 1104 |
|
1105 | 1105 |
return if !$::form->{id}; |
... | ... | |
1112 | 1112 |
# And assign changes from the form to this object. |
1113 | 1113 |
# If the order is loaded from db, check if items are deleted in the form, |
1114 | 1114 |
# remove them form the object and collect them for removing from db on saving. |
1115 |
# Then create/update items from form (via _make_item) and add them.
|
|
1116 |
sub _make_order {
|
|
1115 |
# Then create/update items from form (via make_item) and add them. |
|
1116 |
sub make_order { |
|
1117 | 1117 |
my ($self) = @_; |
1118 | 1118 |
|
1119 | 1119 |
# add_items adds items to an order with no items for saving, but they cannot |
... | ... | |
1122 | 1122 |
my $order; |
1123 | 1123 |
$order = SL::DB::Manager::Order->find_by(id => $::form->{id}) if $::form->{id}; |
1124 | 1124 |
$order ||= SL::DB::Order->new(orderitems => [], |
1125 |
quotation => (any { $self->type eq $_ } (_sales_quotation_type(), _request_quotation_type())));
|
|
1125 |
quotation => (any { $self->type eq $_ } (sales_quotation_type(), request_quotation_type())));
|
|
1126 | 1126 |
|
1127 | 1127 |
my $cv_id_method = $self->cv . '_id'; |
1128 | 1128 |
if (!$::form->{id} && $::form->{$cv_id_method}) { |
1129 | 1129 |
$order->$cv_id_method($::form->{$cv_id_method}); |
1130 |
_setup_order_from_cv($order);
|
|
1130 |
setup_order_from_cv($order); |
|
1131 | 1131 |
} |
1132 | 1132 |
|
1133 | 1133 |
my $form_orderitems = delete $::form->{order}->{orderitems}; |
... | ... | |
1135 | 1135 |
|
1136 | 1136 |
$order->assign_attributes(%{$::form->{order}}); |
1137 | 1137 |
|
1138 |
my $periodic_invoices_config = _make_periodic_invoices_config_from_yaml($form_periodic_invoices_config);
|
|
1138 |
my $periodic_invoices_config = make_periodic_invoices_config_from_yaml($form_periodic_invoices_config); |
|
1139 | 1139 |
$order->periodic_invoices_config($periodic_invoices_config) if $periodic_invoices_config; |
1140 | 1140 |
|
1141 | 1141 |
# remove deleted items |
... | ... | |
1151 | 1151 |
my @items; |
1152 | 1152 |
my $pos = 1; |
1153 | 1153 |
foreach my $form_attr (@{$form_orderitems}) { |
1154 |
my $item = _make_item($order, $form_attr);
|
|
1154 |
my $item = make_item($order, $form_attr); |
|
1155 | 1155 |
$item->position($pos); |
1156 | 1156 |
push @items, $item; |
1157 | 1157 |
$pos++; |
... | ... | |
1165 | 1165 |
# |
1166 | 1166 |
# Make item objects from form values. For items already existing read from db. |
1167 | 1167 |
# Create a new item else. And assign attributes. |
1168 |
sub _make_item {
|
|
1168 |
sub make_item { |
|
1169 | 1169 |
my ($record, $attr) = @_; |
1170 | 1170 |
|
1171 | 1171 |
my $item; |
... | ... | |
1189 | 1189 |
# create a new item |
1190 | 1190 |
# |
1191 | 1191 |
# This is used to add one item |
1192 |
sub _new_item {
|
|
1192 |
sub new_item { |
|
1193 | 1193 |
my ($record, $attr) = @_; |
1194 | 1194 |
|
1195 | 1195 |
my $item = SL::DB::OrderItem->new; |
... | ... | |
1257 | 1257 |
return $item; |
1258 | 1258 |
} |
1259 | 1259 |
|
1260 |
sub _setup_order_from_cv {
|
|
1260 |
sub setup_order_from_cv { |
|
1261 | 1261 |
my ($order) = @_; |
1262 | 1262 |
|
1263 | 1263 |
$order->$_($order->customervendor->$_) for (qw(taxzone_id payment_id delivery_term_id)); |
... | ... | |
1276 | 1276 |
# recalculate prices and taxes |
1277 | 1277 |
# |
1278 | 1278 |
# Using the PriceTaxCalculator. Store linetotals in the item objects. |
1279 |
sub _recalc {
|
|
1279 |
sub recalc { |
|
1280 | 1280 |
my ($self) = @_; |
1281 | 1281 |
|
1282 | 1282 |
# bb: todo: currency later |
... | ... | |
1299 | 1299 |
# get data for saving, printing, ..., that is not changed in the form |
1300 | 1300 |
# |
1301 | 1301 |
# Only cvars for now. |
1302 |
sub _get_unalterable_data {
|
|
1302 |
sub get_unalterable_data { |
|
1303 | 1303 |
my ($self) = @_; |
1304 | 1304 |
|
1305 | 1305 |
foreach my $item (@{ $self->order->items }) { |
... | ... | |
1315 | 1315 |
# delete the order |
1316 | 1316 |
# |
1317 | 1317 |
# And remove related files in the spool directory |
1318 |
sub _delete {
|
|
1318 |
sub delete { |
|
1319 | 1319 |
my ($self) = @_; |
1320 | 1320 |
|
1321 | 1321 |
my $errors = []; |
... | ... | |
1337 | 1337 |
# save the order |
1338 | 1338 |
# |
1339 | 1339 |
# And delete items that are deleted in the form. |
1340 |
sub _save {
|
|
1340 |
sub save { |
|
1341 | 1341 |
my ($self) = @_; |
1342 | 1342 |
|
1343 | 1343 |
my $errors = []; |
... | ... | |
1371 | 1371 |
return $errors; |
1372 | 1372 |
} |
1373 | 1373 |
|
1374 |
sub _workflow_sales_or_purchase_order {
|
|
1374 |
sub workflow_sales_or_purchase_order { |
|
1375 | 1375 |
my ($self) = @_; |
1376 | 1376 |
|
1377 |
my $destination_type = $::form->{type} eq _sales_quotation_type() ? _sales_order_type()
|
|
1378 |
: $::form->{type} eq _request_quotation_type() ? _purchase_order_type()
|
|
1379 |
: $::form->{type} eq _purchase_order_type() ? _sales_order_type()
|
|
1380 |
: $::form->{type} eq _sales_order_type() ? _purchase_order_type()
|
|
1377 |
my $destination_type = $::form->{type} eq sales_quotation_type() ? sales_order_type()
|
|
1378 |
: $::form->{type} eq request_quotation_type() ? purchase_order_type()
|
|
1379 |
: $::form->{type} eq purchase_order_type() ? sales_order_type()
|
|
1380 |
: $::form->{type} eq sales_order_type() ? purchase_order_type()
|
|
1381 | 1381 |
: ''; |
1382 | 1382 |
|
1383 | 1383 |
$self->order(SL::DB::Order->new_from($self->order, destination_type => $destination_type)); |
... | ... | |
1392 | 1392 |
$::form->{type} = $destination_type; |
1393 | 1393 |
$self->type($self->init_type); |
1394 | 1394 |
$self->cv ($self->init_cv); |
1395 |
$self->_check_auth;
|
|
1395 |
$self->check_auth; |
|
1396 | 1396 |
|
1397 |
$self->_recalc();
|
|
1398 |
$self->_get_unalterable_data();
|
|
1399 |
$self->_pre_render();
|
|
1397 |
$self->recalc(); |
|
1398 |
$self->get_unalterable_data(); |
|
1399 |
$self->pre_render(); |
|
1400 | 1400 |
|
1401 | 1401 |
# trigger rendering values for second row/longdescription as hidden, |
1402 | 1402 |
# because they are loaded only on demand. So we need to keep the values |
... | ... | |
1406 | 1406 |
|
1407 | 1407 |
$self->render( |
1408 | 1408 |
'order/form', |
1409 |
title => $self->_get_title_for('edit'),
|
|
1409 |
title => $self->get_title_for('edit'), |
|
1410 | 1410 |
%{$self->{template_args}} |
1411 | 1411 |
); |
1412 | 1412 |
} |
1413 | 1413 |
|
1414 | 1414 |
|
1415 |
sub _pre_render {
|
|
1415 |
sub pre_render { |
|
1416 | 1416 |
my ($self) = @_; |
1417 | 1417 |
|
1418 | 1418 |
$self->{all_taxzones} = SL::DB::Manager::TaxZone->get_all_sorted(); |
... | ... | |
1427 | 1427 |
obsolete => 0 ] ]); |
1428 | 1428 |
$self->{all_delivery_terms} = SL::DB::Manager::DeliveryTerm->get_all_sorted(); |
1429 | 1429 |
$self->{current_employee_id} = SL::DB::Manager::Employee->current->id; |
1430 |
$self->{periodic_invoices_status} = $self->_get_periodic_invoices_status($self->order->periodic_invoices_config);
|
|
1430 |
$self->{periodic_invoices_status} = $self->get_periodic_invoices_status($self->order->periodic_invoices_config); |
|
1431 | 1431 |
$self->{order_probabilities} = [ map { { title => ($_ * 10) . '%', id => $_ * 10 } } (0..10) ]; |
1432 | 1432 |
|
1433 | 1433 |
my $print_form = Form->new(''); |
... | ... | |
1463 | 1463 |
} |
1464 | 1464 |
|
1465 | 1465 |
$::request->{layout}->use_javascript("${_}.js") for qw(kivi.SalesPurchase kivi.Order kivi.File ckeditor/ckeditor ckeditor/adapters/jquery edit_periodic_invoices_config calculate_qty); |
1466 |
$self->_setup_edit_action_bar;
|
|
1466 |
$self->setup_edit_action_bar; |
|
1467 | 1467 |
} |
1468 | 1468 |
|
1469 |
sub _setup_edit_action_bar {
|
|
1469 |
sub setup_edit_action_bar { |
|
1470 | 1470 |
my ($self, %params) = @_; |
1471 | 1471 |
|
1472 |
my $deletion_allowed = (any { $self->type eq $_ } (_sales_quotation_type(), _request_quotation_type()))
|
|
1473 |
|| (($self->type eq _sales_order_type()) && $::instance_conf->get_sales_order_show_delete)
|
|
1474 |
|| (($self->type eq _purchase_order_type()) && $::instance_conf->get_purchase_order_show_delete);
|
|
1472 |
my $deletion_allowed = (any { $self->type eq $_ } (sales_quotation_type(), request_quotation_type()))
|
|
1473 |
|| (($self->type eq sales_order_type()) && $::instance_conf->get_sales_order_show_delete) |
|
1474 |
|| (($self->type eq purchase_order_type()) && $::instance_conf->get_purchase_order_show_delete); |
|
1475 | 1475 |
|
1476 | 1476 |
for my $bar ($::request->layout->get('actionbar')) { |
1477 | 1477 |
$bar->add( |
... | ... | |
1495 | 1495 |
$::instance_conf->get_order_warn_no_deliverydate, |
1496 | 1496 |
], |
1497 | 1497 |
checks => [ 'kivi.Order.check_save_active_periodic_invoices' ], |
1498 |
only_if => (any { $self->type eq $_ } (_sales_order_type(), _purchase_order_type()))
|
|
1498 |
only_if => (any { $self->type eq $_ } (sales_order_type(), purchase_order_type()))
|
|
1499 | 1499 |
], |
1500 | 1500 |
action => [ |
1501 | 1501 |
t8('Save and Invoice'), |
... | ... | |
1511 | 1511 |
action => [ |
1512 | 1512 |
t8('Sales Order'), |
1513 | 1513 |
submit => [ '#order_form', { action => "Order/sales_order" } ], |
1514 |
only_if => (any { $self->type eq $_ } (_sales_quotation_type(), _purchase_order_type())),
|
|
1514 |
only_if => (any { $self->type eq $_ } (sales_quotation_type(), purchase_order_type())),
|
|
1515 | 1515 |
disabled => !$self->order->id ? t8('This object has not been saved yet.') : undef, |
1516 | 1516 |
], |
1517 | 1517 |
action => [ |
1518 | 1518 |
t8('Purchase Order'), |
1519 | 1519 |
submit => [ '#order_form', { action => "Order/purchase_order" } ], |
1520 |
only_if => (any { $self->type eq $_ } (_sales_order_type(), _request_quotation_type())),
|
|
1520 |
only_if => (any { $self->type eq $_ } (sales_order_type(), request_quotation_type())),
|
|
1521 | 1521 |
disabled => !$self->order->id ? t8('This object has not been saved yet.') : undef, |
1522 | 1522 |
], |
1523 | 1523 |
], # end of combobox "Workflow" |
... | ... | |
1553 | 1553 |
} |
1554 | 1554 |
} |
1555 | 1555 |
|
1556 |
sub _create_pdf {
|
|
1556 |
sub generate_pdf {
|
|
1557 | 1557 |
my ($order, $pdf_ref, $params) = @_; |
1558 | 1558 |
|
1559 | 1559 |
my @errors = (); |
... | ... | |
1603 | 1603 |
return @errors; |
1604 | 1604 |
} |
1605 | 1605 |
|
1606 |
sub _get_files_for_email_dialog {
|
|
1606 |
sub get_files_for_email_dialog { |
|
1607 | 1607 |
my ($self) = @_; |
1608 | 1608 |
|
1609 | 1609 |
my %files = map { ($_ => []) } qw(versions files vc_files part_files); |
... | ... | |
1635 | 1635 |
return %files; |
1636 | 1636 |
} |
1637 | 1637 |
|
1638 |
sub _make_periodic_invoices_config_from_yaml {
|
|
1638 |
sub make_periodic_invoices_config_from_yaml { |
|
1639 | 1639 |
my ($yaml_config) = @_; |
1640 | 1640 |
|
1641 | 1641 |
return if !$yaml_config; |
... | ... | |
1645 | 1645 |
} |
1646 | 1646 |
|
1647 | 1647 |
|
1648 |
sub _get_periodic_invoices_status {
|
|
1648 |
sub get_periodic_invoices_status { |
|
1649 | 1649 |
my ($self, $config) = @_; |
1650 | 1650 |
|
1651 |
return if $self->type ne _sales_order_type();
|
|
1651 |
return if $self->type ne sales_order_type(); |
|
1652 | 1652 |
return t8('not configured') if !$config; |
1653 | 1653 |
|
1654 | 1654 |
my $active = ('HASH' eq ref $config) ? $config->{active} |
... | ... | |
1658 | 1658 |
return $active ? t8('active') : t8('inactive'); |
1659 | 1659 |
} |
1660 | 1660 |
|
1661 |
sub _get_title_for {
|
|
1661 |
sub get_title_for { |
|
1662 | 1662 |
my ($self, $action) = @_; |
1663 | 1663 |
|
1664 | 1664 |
return '' if none { lc($action)} qw(add edit); |
... | ... | |
1674 | 1674 |
# $::locale->text("Edit Request for Quotation"); |
1675 | 1675 |
|
1676 | 1676 |
$action = ucfirst(lc($action)); |
1677 |
return $self->type eq _sales_order_type() ? $::locale->text("$action Sales Order")
|
|
1678 |
: $self->type eq _purchase_order_type() ? $::locale->text("$action Purchase Order")
|
|
1679 |
: $self->type eq _sales_quotation_type() ? $::locale->text("$action Quotation")
|
|
1680 |
: $self->type eq _request_quotation_type() ? $::locale->text("$action Request for Quotation")
|
|
1677 |
return $self->type eq sales_order_type() ? $::locale->text("$action Sales Order") |
|
1678 |
: $self->type eq purchase_order_type() ? $::locale->text("$action Purchase Order") |
|
1679 |
: $self->type eq sales_quotation_type() ? $::locale->text("$action Quotation") |
|
1680 |
: $self->type eq request_quotation_type() ? $::locale->text("$action Request for Quotation") |
|
1681 | 1681 |
: ''; |
1682 | 1682 |
} |
1683 | 1683 |
|
1684 |
sub _sales_order_type {
|
|
1684 |
sub sales_order_type { |
|
1685 | 1685 |
'sales_order'; |
1686 | 1686 |
} |
1687 | 1687 |
|
1688 |
sub _purchase_order_type {
|
|
1688 |
sub purchase_order_type { |
|
1689 | 1689 |
'purchase_order'; |
1690 | 1690 |
} |
1691 | 1691 |
|
1692 |
sub _sales_quotation_type {
|
|
1692 |
sub sales_quotation_type { |
|
1693 | 1693 |
'sales_quotation'; |
1694 | 1694 |
} |
1695 | 1695 |
|
1696 |
sub _request_quotation_type {
|
|
1696 |
sub request_quotation_type { |
|
1697 | 1697 |
'request_quotation'; |
1698 | 1698 |
} |
1699 | 1699 |
|
1700 |
sub _nr_key {
|
|
1701 |
return $_[0]->type eq _sales_order_type() ? 'ordnumber'
|
|
1702 |
: $_[0]->type eq _purchase_order_type() ? 'ordnumber'
|
|
1703 |
: $_[0]->type eq _sales_quotation_type() ? 'quonumber'
|
|
1704 |
: $_[0]->type eq _request_quotation_type() ? 'quonumber'
|
|
1700 |
sub nr_key { |
|
1701 |
return $_[0]->type eq sales_order_type() ? 'ordnumber' |
|
1702 |
: $_[0]->type eq purchase_order_type() ? 'ordnumber' |
|
1703 |
: $_[0]->type eq sales_quotation_type() ? 'quonumber' |
|
1704 |
: $_[0]->type eq request_quotation_type() ? 'quonumber' |
|
1705 | 1705 |
: ''; |
1706 | 1706 |
} |
1707 | 1707 |
|
Auch abrufbar als: Unified diff
Auftrags-Controller: kein Unterstrich vor privaten Funktionen
In einem Controller wird den von aussen zugänglichen Funktionen "action_"
vorangestellt, deshalb ist zur Unterscheidung das Voranstellen eines
Unterstrichs unnötig und verschlechtert die Lesbarkeit.