Revision 8ad661b7
Von Bernd Bleßmann vor fast 4 Jahren hinzugefügt
SL/Controller/Order.pm | ||
---|---|---|
43 | 43 |
use Rose::Object::MakeMethods::Generic |
44 | 44 |
( |
45 | 45 |
scalar => [ qw(item_ids_to_delete is_custom_shipto_to_delete) ], |
46 |
'scalar --get_set_init' => [ qw(order valid_types type cv p multi_items_models all_price_factors search_cvpartnumber show_update_button) ],
|
|
46 |
'scalar --get_set_init' => [ qw(order valid_types type cv p all_price_factors search_cvpartnumber show_update_button) ], |
|
47 | 47 |
); |
48 | 48 |
|
49 | 49 |
|
... | ... | |
791 | 791 |
$self->js->render(); |
792 | 792 |
} |
793 | 793 |
|
794 |
# open the dialog for entering multiple items at once |
|
795 |
sub action_show_multi_items_dialog { |
|
796 |
$_[0]->render('order/tabs/_multi_items_dialog', { layout => 0 }, |
|
797 |
all_partsgroups => SL::DB::Manager::PartsGroup->get_all); |
|
798 |
} |
|
799 |
|
|
800 |
# update the filter results in the multi item dialog |
|
801 |
sub action_multi_items_update_result { |
|
802 |
my $max_count = 100; |
|
803 |
|
|
804 |
$::form->{multi_items}->{filter}->{obsolete} = 0; |
|
805 |
|
|
806 |
my $count = $_[0]->multi_items_models->count; |
|
807 |
|
|
808 |
if ($count == 0) { |
|
809 |
my $text = SL::Presenter::EscapedText->new(text => $::locale->text('No results.')); |
|
810 |
$_[0]->render($text, { layout => 0 }); |
|
811 |
} elsif ($count > $max_count) { |
|
812 |
my $text = SL::Presenter::EscapedText->new(text => $::locale->text('Too many results (#1 from #2).', $count, $max_count)); |
|
813 |
$_[0]->render($text, { layout => 0 }); |
|
814 |
} else { |
|
815 |
my $multi_items = $_[0]->multi_items_models->get; |
|
816 |
$_[0]->render('order/tabs/_multi_items_result', { layout => 0 }, |
|
817 |
multi_items => $multi_items); |
|
818 |
} |
|
819 |
} |
|
820 |
|
|
821 | 794 |
# add item rows for multiple items at once |
822 | 795 |
sub action_add_multi_items { |
823 | 796 |
my ($self) = @_; |
824 | 797 |
|
825 |
my @form_attr = grep { $_->{qty_as_number} } @{ $::form->{add_multi_items} };
|
|
798 |
my @form_attr = grep { $_->{qty_as_number} } @{ $::form->{add_items} }; |
|
826 | 799 |
return $self->js->render() unless scalar @form_attr; |
827 | 800 |
|
828 | 801 |
my @items; |
... | ... | |
867 | 840 |
} |
868 | 841 |
|
869 | 842 |
$self->js |
870 |
->run('kivi.Order.close_multi_items_dialog')
|
|
843 |
->run('kivi.Part.close_picker_dialogs')
|
|
871 | 844 |
->run('kivi.Order.init_row_handlers') |
872 | 845 |
->run('kivi.Order.renumber_positions') |
873 | 846 |
->focus('#add_item_parts_id_name'); |
... | ... | |
1183 | 1156 |
$_[0]->make_order; |
1184 | 1157 |
} |
1185 | 1158 |
|
1186 |
# model used to filter/display the parts in the multi-items dialog |
|
1187 |
sub init_multi_items_models { |
|
1188 |
SL::Controller::Helper::GetModels->new( |
|
1189 |
controller => $_[0], |
|
1190 |
model => 'Part', |
|
1191 |
with_objects => [ qw(unit_obj) ], |
|
1192 |
disable_plugin => 'paginated', |
|
1193 |
source => $::form->{multi_items}, |
|
1194 |
sorted => { |
|
1195 |
_default => { |
|
1196 |
by => 'partnumber', |
|
1197 |
dir => 1, |
|
1198 |
}, |
|
1199 |
partnumber => t8('Partnumber'), |
|
1200 |
description => t8('Description')} |
|
1201 |
); |
|
1202 |
} |
|
1203 |
|
|
1204 | 1159 |
sub init_all_price_factors { |
1205 | 1160 |
SL::DB::Manager::PriceFactor->get_all; |
1206 | 1161 |
} |
... | ... | |
2175 | 2130 |
|
2176 | 2131 |
Displaying tax information |
2177 | 2132 |
|
2178 |
=item * C<template/webpages/order/tabs/_multi_items_dialog.html> |
|
2179 |
|
|
2180 |
Dialog for entering more than one item at once |
|
2181 |
|
|
2182 |
=item * C<template/webpages/order/tabs/_multi_items_result.html> |
|
2183 |
|
|
2184 |
Results for the filter in the multi items dialog |
|
2185 |
|
|
2186 | 2133 |
=item * C<template/webpages/order/tabs/_price_sources_dialog.html> |
2187 | 2134 |
|
2188 | 2135 |
Dialog for selecting price and discount sources |
... | ... | |
2256 | 2203 |
This behavior was implemented intentionally. But we can discuss, which behavior |
2257 | 2204 |
should be implemented. |
2258 | 2205 |
|
2259 |
=item * |
|
2260 |
|
|
2261 |
C<show_multi_items_dialog> does not use the currently inserted string for |
|
2262 |
filtering. |
|
2263 |
|
|
2264 | 2206 |
=back |
2265 | 2207 |
|
2266 | 2208 |
=head1 To discuss / Nice to have |
js/kivi.Order.js | ||
---|---|---|
458 | 458 |
$.post("controller.pl", data, kivi.eval_json_result); |
459 | 459 |
}; |
460 | 460 |
|
461 |
ns.setup_multi_items_dialog = function() { |
|
462 |
$('#multi_items_filter_table input, #multi_items_filter_table select').keydown(function(event) { |
|
463 |
if (event.keyCode == 13) { |
|
464 |
event.preventDefault(); |
|
465 |
ns.multi_items_dialog_update_result(); |
|
466 |
return false; |
|
467 |
} |
|
468 |
}); |
|
469 |
|
|
470 |
$('#multi_items_filter_all_substr_multi_ilike').focus(); |
|
471 |
}; |
|
472 |
|
|
473 |
ns.show_multi_items_dialog = function() { |
|
474 |
if (!ns.check_cv()) return; |
|
475 |
|
|
476 |
$('#row_table_id thead a img').remove(); |
|
477 |
|
|
478 |
kivi.popup_dialog({ |
|
479 |
url: 'controller.pl?action=Order/show_multi_items_dialog', |
|
480 |
data: { type: $('#type').val() }, |
|
481 |
id: 'jq_multi_items_dialog', |
|
482 |
load: kivi.Order.setup_multi_items_dialog, |
|
483 |
dialog: { |
|
484 |
title: kivi.t8('Add multiple items'), |
|
485 |
width: 800, |
|
486 |
height: 500 |
|
487 |
} |
|
488 |
}); |
|
489 |
return true; |
|
490 |
}; |
|
491 |
|
|
492 |
ns.close_multi_items_dialog = function() { |
|
493 |
$('#jq_multi_items_dialog').dialog('close'); |
|
494 |
}; |
|
495 |
|
|
496 |
ns.multi_items_dialog_update_result = function() { |
|
497 |
var data = $('#multi_items_form').serializeArray(); |
|
498 |
data.push({ name: 'type', value: $('#type').val() }); |
|
499 |
$.ajax({ |
|
500 |
url: 'controller.pl?action=Order/multi_items_update_result', |
|
501 |
data: data, |
|
502 |
method: 'post', |
|
503 |
success: function(data) { |
|
504 |
$('#multi_items_result').html(data); |
|
505 |
ns.multi_items_dialog_enable_continue(); |
|
506 |
ns.multi_items_result_setup_events(); |
|
507 |
} |
|
508 |
}); |
|
509 |
}; |
|
510 |
|
|
511 |
ns.multi_items_dialog_disable_continue = function() { |
|
512 |
// disable keydown-event and continue button to prevent |
|
513 |
// impatient users to add parts multiple times |
|
514 |
$('#multi_items_result input, #multi_items_position').off("keydown"); |
|
515 |
$('#multi_items_dialog_continue_button').prop('disabled', true); |
|
516 |
}; |
|
517 |
|
|
518 |
ns.multi_items_dialog_enable_continue = function() { |
|
519 |
$('#multi_items_result input, #multi_items_position').keydown(function(event) { |
|
520 |
if(event.keyCode == 13) { |
|
521 |
event.preventDefault(); |
|
522 |
ns.add_multi_items(); |
|
523 |
return false; |
|
524 |
} |
|
525 |
}); |
|
526 |
$('#multi_items_dialog_continue_button').prop('disabled', false); |
|
527 |
}; |
|
528 |
|
|
529 |
ns.multi_items_result_setup_events = function() { |
|
530 |
$('#multi_items_all_qty').change(ns.reformat_number); |
|
531 |
$('#multi_items_all_qty').change(function(event) { |
|
532 |
$('.multi_items_qty').val($(event.target).val()); |
|
533 |
}); |
|
534 |
$('.multi_items_qty').change(ns.reformat_number); |
|
535 |
} |
|
536 |
|
|
537 |
ns.add_multi_items = function() { |
|
538 |
// rows at all |
|
539 |
var n_rows = $('.multi_items_qty').length; |
|
540 |
if (n_rows == 0) return; |
|
541 |
|
|
542 |
// filled rows |
|
543 |
n_rows = $('.multi_items_qty').filter(function() { |
|
544 |
return $(this).val().length > 0; |
|
545 |
}).length; |
|
546 |
if (n_rows == 0) return; |
|
547 |
|
|
548 |
ns.multi_items_dialog_disable_continue(); |
|
549 |
|
|
461 |
ns.add_multi_items = function(data) { |
|
550 | 462 |
var insert_before_item_id = ns.get_insert_before_item_id($('#multi_items_position').val()); |
551 |
|
|
552 |
var data = $('#order_form').serializeArray(); |
|
553 |
data = data.concat($('#multi_items_form').serializeArray()); |
|
463 |
data = data.concat($('#order_form').serializeArray()); |
|
554 | 464 |
data.push({ name: 'action', value: 'Order/add_multi_items' }, |
555 | 465 |
{ name: 'insert_before_item_id', value: insert_before_item_id }); |
556 | 466 |
$.post("controller.pl", data, kivi.eval_json_result); |
557 | 467 |
}; |
558 | 468 |
|
559 |
ns.set_input_to_one = function(clicked) { |
|
560 |
if ($(clicked).val() == '') { |
|
561 |
$(clicked).val(kivi.format_amount(1.00, -2)); |
|
562 |
} |
|
563 |
$(clicked).select(); |
|
564 |
}; |
|
565 |
|
|
566 | 469 |
ns.delete_order_item_row = function(clicked) { |
567 | 470 |
var row = $(clicked).parents("tbody").first(); |
568 | 471 |
$(row).remove(); |
templates/webpages/order/tabs/_item_input.html | ||
---|---|---|
19 | 19 |
<td> |
20 | 20 |
[%- SET PARAM_KEY = SELF.cv == "customer" ? 'with_customer_partnumber' : 'with_makemodel' -%] |
21 | 21 |
[%- SET PARAM_VAL = SELF.search_cvpartnumber -%] |
22 |
[% P.part.picker('add_item.parts_id', '', fat_set_item=1, style='width: 300px', class="add_item_input", $PARAM_KEY=PARAM_VAL) %]</td> |
|
22 |
[% P.part.picker('add_item.parts_id', '', style='width: 300px', class="add_item_input", |
|
23 |
fat_set_item=1, |
|
24 |
multiple_pos_input=1, |
|
25 |
action={set_multi_items='kivi.Order.add_multi_items'}, |
|
26 |
$PARAM_KEY=PARAM_VAL) %]</td> |
|
23 | 27 |
<td>[% L.input_tag('add_item.description', '', class="add_item_input") %]</td> |
24 | 28 |
<td> |
25 | 29 |
[% L.input_tag('add_item.qty_as_number', '', size = 5, class="add_item_input numeric") %] |
templates/webpages/order/tabs/_multi_items_dialog.html | ||
---|---|---|
1 |
[%- USE T8 %][%- USE HTML %][%- USE L %][%- USE LxERP %] |
|
2 |
|
|
3 |
<form method="post" id="multi_items_form" method="POST"> |
|
4 |
|
|
5 |
<table id='multi_items_filter_table'> |
|
6 |
<tr> |
|
7 |
<th>[%- LxERP.t8("Description") %]/[%- LxERP.t8("Partnumber") %]:</th> |
|
8 |
<td>[%- L.input_tag('multi_items.filter.all:substr:multi::ilike', '') %]</td> |
|
9 |
<th>[%- LxERP.t8("Partsgroup") %]</th> |
|
10 |
<td>[%- L.select_tag('multi_items.filter.partsgroup_id', all_partsgroups, title_key='displayable_name', value_key='id', with_empty=1) %]</td> |
|
11 |
<tr> |
|
12 |
</table> |
|
13 |
|
|
14 |
[% L.button_tag('kivi.Order.multi_items_dialog_update_result()', LxERP.t8('Filter')) %] |
|
15 |
[% L.button_tag('$("#multi_items_form").resetForm()', LxERP.t8('Reset')) %] |
|
16 |
|
|
17 |
<hr> |
|
18 |
<div id='multi_items_result'></div> |
|
19 |
<hr> |
|
20 |
|
|
21 |
[% 'At position' | $T8 %] |
|
22 |
[% L.input_tag('multi_items.position', '', size = 5, class="numeric") %]</td> |
|
23 |
[% L.button_tag('kivi.Order.add_multi_items()', LxERP.t8('Continue'), id='multi_items_dialog_continue_button') %] |
|
24 |
<a href="#" onclick="kivi.Order.close_multi_items_dialog();">[%- LxERP.t8("Cancel") %]</a> |
|
25 |
|
|
26 |
|
|
27 |
</form> |
templates/webpages/order/tabs/_multi_items_result.html | ||
---|---|---|
1 |
[%- USE T8 %][%- USE HTML %][%- USE L %][%- USE LxERP %] |
|
2 |
|
|
3 |
<table width="100%"> |
|
4 |
<tr> |
|
5 |
<td>[% 'for all' | $T8 %] |
|
6 |
<td>[% L.input_tag("multi_items.all_qty", '', size = 5, class='numeric') %]</td> |
|
7 |
</tr> |
|
8 |
<tr> |
|
9 |
<td colspan="5"><hr></td> |
|
10 |
</tr> |
|
11 |
[%- FOREACH item = multi_items %] |
|
12 |
<tr> |
|
13 |
<td></td> |
|
14 |
<td> |
|
15 |
[% L.hidden_tag("add_multi_items[+].parts_id", item.id) %] |
|
16 |
[% L.input_tag("add_multi_items[].qty_as_number", '', size = 5, |
|
17 |
class = 'multi_items_qty numeric', onclick = 'kivi.Order.set_input_to_one(this)') %] |
|
18 |
</td> |
|
19 |
<td>[% HTML.escape(item.unit) %]</td> |
|
20 |
<td>[% HTML.escape(item.partnumber) %]</td> |
|
21 |
<td>[% HTML.escape(item.description) %]</td> |
|
22 |
</tr> |
|
23 |
[%- END %] |
|
24 |
</table> |
templates/webpages/order/tabs/basic_data.html | ||
---|---|---|
227 | 227 |
|
228 | 228 |
[%- PROCESS order/tabs/_item_input.html SELF=SELF %] |
229 | 229 |
|
230 |
[% L.button_tag('kivi.Order.show_multi_items_dialog()', LxERP.t8('Add multiple items')) %]
|
|
230 |
[% L.button_tag('$("#add_item_parts_id").data("part_picker").o.multiple=1; $("#add_item_parts_id").data("part_picker").open_dialog()', LxERP.t8('Add multiple items')) %]
|
|
231 | 231 |
|
232 | 232 |
<table width="100%"> |
233 | 233 |
<tr> |
Auch abrufbar als: Unified diff
Auftrags-Controller: Artikel-Mehrfachauswahl auf die des PartPickers umgestellt