1 namespace('kivi.Order', function(ns) {
2 ns.check_cv = function() {
3 if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation') {
4 if ($('#order_customer_id').val() === '') {
5 alert(kivi.t8('Please select a customer.'));
9 if ($('#order_vendor_id').val() === '') {
10 alert(kivi.t8('Please select a vendor.'));
17 ns.check_duplicate_parts = function(question) {
18 var id_arr = $('[name="order.orderitems[].parts_id"]').map(function() { return this.value; }).get();
20 var i, obj = {}, pos = [];
22 for (i = 0; i < id_arr.length; i++) {
24 if (obj.hasOwnProperty(id)) {
31 question = question || kivi.t8("Do you really want to save?");
32 return confirm(kivi.t8("There are duplicate parts at positions") + "\n"
33 + pos.join(', ') + "\n"
39 ns.check_valid_reqdate = function() {
40 if ($('#order_reqdate_as_date').val() === '') {
41 alert(kivi.t8('Please select a delivery date.'));
48 ns.save = function(action, warn_on_duplicates, warn_on_reqdate) {
49 if (!ns.check_cv()) return;
50 if (warn_on_duplicates && !ns.check_duplicate_parts()) return;
51 if (warn_on_reqdate && !ns.check_valid_reqdate()) return;
53 var data = $('#order_form').serializeArray();
54 data.push({ name: 'action', value: 'Order/' + action });
56 $.post("controller.pl", data, kivi.eval_json_result);
59 ns.delete_order = function() {
60 var data = $('#order_form').serializeArray();
61 data.push({ name: 'action', value: 'Order/delete' });
63 $.post("controller.pl", data, kivi.eval_json_result);
66 ns.show_print_options = function(warn_on_duplicates) {
67 if (!ns.check_cv()) return;
68 if (warn_on_duplicates && !ns.check_duplicate_parts(kivi.t8("Do you really want to print?"))) return;
73 title: kivi.t8('Print options'),
80 ns.print = function() {
81 $('#print_options').dialog('close');
83 var data = $('#order_form').serializeArray();
84 data = data.concat($('#print_options_form').serializeArray());
85 data.push({ name: 'action', value: 'Order/print' });
87 $.post("controller.pl", data, kivi.eval_json_result);
90 ns.email = function(warn_on_duplicates) {
91 if (warn_on_duplicates && !ns.check_duplicate_parts(kivi.t8("Do you really want to send by mail?"))) return;
92 if (!ns.check_cv()) return;
94 var data = $('#order_form').serializeArray();
95 data.push({ name: 'action', value: 'Order/show_email_dialog' });
97 $.post("controller.pl", data, kivi.eval_json_result);
102 ns.setup_send_email_dialog = function() {
103 kivi.SalesPurchase.show_all_print_options_elements();
104 kivi.SalesPurchase.show_print_options_elements([ 'sendmode', 'media', 'copies', 'remove_draft' ], false);
106 $('#print_options_form table').first().remove().appendTo('#email_form_print_options');
108 var to_focus = $('#email_form_to').val() === '' ? 'to' : 'subject';
109 $('#email_form_' + to_focus).focus();
112 ns.finish_send_email_dialog = function() {
113 kivi.SalesPurchase.show_all_print_options_elements();
115 $('#email_form_print_options table').first().remove().prependTo('#print_options_form');
119 ns.show_email_dialog = function(html) {
120 var id = 'send_email_dialog';
121 var dialog_params = {
125 title: kivi.t8('Send email'),
127 beforeClose: kivi.Order.finish_send_email_dialog,
128 close: function(event, ui) {
129 email_dialog.remove();
133 $('#' + id).remove();
135 email_dialog = $('<div style="display:none" id="' + id + '"></div>').appendTo('body');
136 email_dialog.html(html);
137 email_dialog.dialog(dialog_params);
139 kivi.Order.setup_send_email_dialog();
141 $('.cancel').click(ns.close_email_dialog);
146 ns.send_email = function() {
147 var data = $('#order_form').serializeArray();
148 data = data.concat($('[name^="email_form."]').serializeArray());
149 data = data.concat($('[name^="print_options."]').serializeArray());
150 data.push({ name: 'action', value: 'Order/send_email' });
151 $.post("controller.pl", data, kivi.eval_json_result);
154 ns.close_email_dialog = function() {
155 email_dialog.dialog("close");
158 ns.set_number_in_title = function(elt) {
159 $('#nr_in_title').html($(elt).val());
162 ns.reload_cv_dependant_selections = function() {
163 var data = $('#order_form').serializeArray();
164 data.push({ name: 'action', value: 'Order/customer_vendor_changed' });
166 $.post("controller.pl", data, kivi.eval_json_result);
169 ns.reformat_number = function(event) {
170 $(event.target).val(kivi.format_amount(kivi.parse_amount($(event.target).val()), -2));
173 ns.recalc_amounts_and_taxes = function() {
174 var data = $('#order_form').serializeArray();
175 data.push({ name: 'action', value: 'Order/recalc_amounts_and_taxes' });
177 $.post("controller.pl", data, kivi.eval_json_result);
180 ns.unit_change = function(event) {
181 var row = $(event.target).parents("tbody").first();
182 var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
183 var sellprice_dom = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
184 var select_elt = $(row).find('[name="order.orderitems[].unit"]');
186 var oldval = $(select_elt).data('oldval');
187 $(select_elt).data('oldval', $(select_elt).val());
189 var data = $('#order_form').serializeArray();
190 data.push({ name: 'action', value: 'Order/unit_changed' },
191 { name: 'item_id', value: item_id_dom.val() },
192 { name: 'old_unit', value: oldval },
193 { name: 'sellprice_dom_id', value: sellprice_dom.attr('id') });
195 $.post("controller.pl", data, kivi.eval_json_result);
198 ns.update_sellprice = function(item_id, price_str) {
199 var row = $('#item_' + item_id).parents("tbody").first();
200 var price_elt = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
201 var html_elt = $(row).find('[name="sellprice_text"]');
202 price_elt.val(price_str);
203 html_elt.html(price_str);
206 ns.load_second_row = function(row) {
207 var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
208 var div_elt = $(row).find('[name="second_row"]');
210 if ($(div_elt).data('loaded') == 1) {
213 var data = $('#order_form').serializeArray();
214 data.push({ name: 'action', value: 'Order/load_second_rows' },
215 { name: 'item_ids[]', value: item_id_dom.val() });
217 $.post("controller.pl", data, kivi.eval_json_result);
220 ns.load_all_second_rows = function() {
221 var rows = $('.row_entry').filter(function(idx, elt) {
222 return $(elt).find('[name="second_row"]').data('loaded') != 1;
225 var item_ids = $.map(rows, function(elt) {
226 var item_id = $(elt).find('[name="orderitem_ids[+]"]').val();
227 return { name: 'item_ids[]', value: item_id };
230 if (item_ids.length == 0) {
234 var data = $('#order_form').serializeArray();
235 data.push({ name: 'action', value: 'Order/load_second_rows' });
236 data = data.concat(item_ids);
238 $.post("controller.pl", data, kivi.eval_json_result);
241 ns.hide_second_row = function(row) {
242 $(row).children().not(':first').hide();
243 $(row).data('expanded', 0);
244 var elt = $(row).find('.expand');
245 elt.attr('src', "image/expand.svg");
246 elt.attr('alt', kivi.t8('Show details'));
247 elt.attr('title', kivi.t8('Show details'));
250 ns.show_second_row = function(row) {
251 $(row).children().not(':first').show();
252 $(row).data('expanded', 1);
253 var elt = $(row).find('.expand');
254 elt.attr('src', "image/collapse.svg");
255 elt.attr('alt', kivi.t8('Hide details'));
256 elt.attr('title', kivi.t8('Hide details'));
259 ns.toggle_second_row = function(row) {
260 if ($(row).data('expanded') == 1) {
261 ns.hide_second_row(row);
263 ns.show_second_row(row);
267 ns.init_row_handlers = function() {
268 kivi.run_once_for('.recalc', 'on_change_recalc', function(elt) {
269 $(elt).change(ns.recalc_amounts_and_taxes);
272 kivi.run_once_for('.reformat_number', 'on_change_reformat', function(elt) {
273 $(elt).change(ns.reformat_number);
276 kivi.run_once_for('.unitselect', 'on_change_unit_with_oldval', function(elt) {
277 $(elt).data('oldval', $(elt).val());
278 $(elt).change(ns.unit_change);
281 kivi.run_once_for('.row_entry', 'on_kbd_click_show_hide', function(elt) {
282 $(elt).keydown(function(event) {
284 if (event.keyCode == 40 && event.shiftKey === true) {
286 event.preventDefault();
287 row = $(event.target).parents(".row_entry").first();
288 ns.load_second_row(row);
289 ns.show_second_row(row);
292 if (event.keyCode == 38 && event.shiftKey === true) {
294 event.preventDefault();
295 row = $(event.target).parents(".row_entry").first();
296 ns.hide_second_row(row);
302 kivi.run_once_for('.expand', 'expand_second_row', function(elt) {
303 $(elt).click(function(event) {
304 event.preventDefault();
305 var row = $(event.target).parents(".row_entry").first();
306 ns.load_second_row(row);
307 ns.toggle_second_row(row);
314 ns.redisplay_line_values = function(is_sales, data) {
315 $('.row_entry').each(function(idx, elt) {
316 $(elt).find('[name="linetotal"]').html(data[idx][0]);
317 if (is_sales && $(elt).find('[name="second_row"]').data('loaded') == 1) {
318 var mt = data[idx][1];
319 var mp = data[idx][2];
321 if (mt[0] === '-') h += ' class="plus0"';
322 h += '>' + mt + ' ' + mp + '%';
324 $(elt).find('[name="linemargin"]').html(h);
329 ns.redisplay_cvpartnumbers = function(data) {
330 $('.row_entry').each(function(idx, elt) {
331 $(elt).find('[name="cvpartnumber"]').html(data[idx][0]);
335 ns.renumber_positions = function() {
336 $('.row_entry [name="position"]').each(function(idx, elt) {
341 ns.reorder_items = function(order_by) {
342 var dir = $('#' + order_by + '_header_id a img').attr("data-sort-dir");
343 $('#row_table_id thead a img').remove();
348 src = "image/up.png";
351 src = "image/down.png";
354 $('#' + order_by + '_header_id a').append('<img border=0 data-sort-dir=' + dir + ' src=' + src + ' alt="' + kivi.t8('sort items') + '">');
356 var data = $('#order_form').serializeArray();
357 data.push({ name: 'action', value: 'Order/reorder_items' },
358 { name: 'order_by', value: order_by },
359 { name: 'sort_dir', value: dir });
361 $.post("controller.pl", data, kivi.eval_json_result);
364 ns.redisplay_items = function(data) {
365 var old_rows = $('.row_entry').detach();
367 $(data).each(function(idx, elt) {
368 new_rows.push(old_rows[elt.old_pos - 1]);
370 $(new_rows).appendTo($('#row_table_id'));
371 ns.renumber_positions();
374 ns.add_item = function() {
375 if ($('#add_item_parts_id').val() === '') return;
376 if (!ns.check_cv()) return;
378 $('#row_table_id thead a img').remove();
380 var data = $('#order_form').serializeArray();
381 data.push({ name: 'action', value: 'Order/add_item' });
383 $.post("controller.pl", data, kivi.eval_json_result);
386 ns.setup_multi_items_dialog = function() {
387 $('#multi_items_filter_table input, #multi_items_filter_table select').keydown(function(event) {
388 if (event.keyCode == 13) {
389 event.preventDefault();
390 ns.multi_items_dialog_update_result();
395 $('#multi_items_filter_all_substr_multi_ilike').focus();
398 ns.show_multi_items_dialog = function() {
399 if (!ns.check_cv()) return;
401 $('#row_table_id thead a img').remove();
404 url: 'controller.pl?action=Order/show_multi_items_dialog',
405 data: { type: $('#type').val() },
406 id: 'jq_multi_items_dialog',
407 load: kivi.Order.setup_multi_items_dialog,
409 title: kivi.t8('Add multiple items'),
417 ns.close_multi_items_dialog = function() {
418 $('#jq_multi_items_dialog').dialog('close');
421 ns.multi_items_dialog_update_result = function() {
422 var data = $('#multi_items_form').serializeArray();
423 data.push({ name: 'type', value: $('#type').val() });
425 url: 'controller.pl?action=Order/multi_items_update_result',
428 success: function(data) {
429 $('#multi_items_result').html(data);
430 ns.multi_items_dialog_enable_continue();
431 ns.multi_items_result_setup_events();
436 ns.multi_items_dialog_disable_continue = function() {
437 // disable keydown-event and continue button to prevent
438 // impatient users to add parts multiple times
439 $('#multi_items_result input').off("keydown");
440 $('#multi_items_dialog_continue_button').prop('disabled', true);
443 ns.multi_items_dialog_enable_continue = function() {
444 $('#multi_items_result input').keydown(function(event) {
445 if(event.keyCode == 13) {
446 event.preventDefault();
447 ns.add_multi_items();
451 $('#multi_items_dialog_continue_button').prop('disabled', false);
454 ns.multi_items_result_setup_events = function() {
455 $('#multi_items_all_qty').change(ns.reformat_number);
456 $('#multi_items_all_qty').change(function(event) {
457 $('.multi_items_qty').val($(event.target).val());
459 $('.multi_items_qty').change(ns.reformat_number);
462 ns.add_multi_items = function() {
464 var n_rows = $('.multi_items_qty').length;
465 if (n_rows == 0) return;
468 n_rows = $('.multi_items_qty').filter(function() {
469 return $(this).val().length > 0;
471 if (n_rows == 0) return;
473 ns.multi_items_dialog_disable_continue();
475 var data = $('#order_form').serializeArray();
476 data = data.concat($('#multi_items_form').serializeArray());
477 data.push({ name: 'action', value: 'Order/add_multi_items' });
478 $.post("controller.pl", data, kivi.eval_json_result);
481 ns.set_input_to_one = function(clicked) {
482 if ($(clicked).val() == '') {
483 $(clicked).val(kivi.format_amount(1.00, -2));
488 ns.delete_order_item_row = function(clicked) {
489 var row = $(clicked).parents("tbody").first();
492 ns.renumber_positions();
493 ns.recalc_amounts_and_taxes();
496 ns.row_table_scroll_down = function() {
497 $('#row_table_scroll_id').scrollTop($('#row_table_scroll_id')[0].scrollHeight);
500 ns.show_longdescription_dialog = function(clicked) {
501 var row = $(clicked).parents("tbody").first();
502 var position = $(row).find('[name="position"]').html();
503 var partnumber = $(row).find('[name="partnumber"]').html();
504 var description_elt = $(row).find('[name="order.orderitems[].description"]');
505 var description = description_elt.val();
506 var longdescription_elt = $(row).find('[name="order.orderitems[].longdescription"]');
509 if (!longdescription_elt.length) {
511 { name: 'action', value: 'Order/get_item_longdescription' },
512 { name: 'type', value: $('#type').val() },
513 { name: 'item_id', value: $(row).find('[name="order.orderitems[+].id"]').val() },
514 { name: 'parts_id', value: $(row).find('[name="order.orderitems[].parts_id"]').val() }
518 url: 'controller.pl',
523 success: function(val) {
524 longdescription = val;
528 longdescription = longdescription_elt.val();
532 runningnumber: position,
533 partnumber: partnumber,
534 description: description,
535 default_longdescription: longdescription,
536 set_function: function(val) {
537 longdescription_elt.remove();
538 $('<input type="hidden" name="order.orderitems[].longdescription">').insertAfter(description_elt).val(val);
542 kivi.SalesPurchase.edit_longdescription_with_params(params);
545 ns.price_chooser_item_row = function(clicked) {
546 if (!ns.check_cv()) return;
547 var row = $(clicked).parents("tbody").first();
548 var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
550 var data = $('#order_form').serializeArray();
551 data.push({ name: 'action', value: 'Order/price_popup' },
552 { name: 'item_id', value: item_id_dom.val() });
554 $.post("controller.pl", data, kivi.eval_json_result);
557 ns.update_price_source = function(item_id, source, descr, price_str, price_editable) {
558 var row = $('#item_' + item_id).parents("tbody").first();
559 var source_elt = $(row).find('[name="order.orderitems[].active_price_source"]');
560 var button_elt = $(row).find('[name="price_chooser_button"]');
562 button_elt.val(button_elt.val().replace(/.*\|/, descr + " |"));
563 source_elt.val(source);
565 var editable_div_elt = $(row).find('[name="editable_price"]');
566 var not_editable_div_elt = $(row).find('[name="not_editable_price"]');
567 if (price_editable == 1 && source === '') {
569 $(editable_div_elt).show();
570 $(not_editable_div_elt).hide();
571 $(editable_div_elt).find(':input').prop("disabled", false);
572 $(not_editable_div_elt).find(':input').prop("disabled", true);
575 $(editable_div_elt).hide();
576 $(not_editable_div_elt).show();
577 $(editable_div_elt).find(':input').prop("disabled", true);
578 $(not_editable_div_elt).find(':input').prop("disabled", false);
582 var price_elt = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
583 var html_elt = $(row).find('[name="sellprice_text"]');
584 price_elt.val(price_str);
585 html_elt.html(price_str);
586 ns.recalc_amounts_and_taxes();
589 kivi.io.close_dialog();
592 ns.update_discount_source = function(item_id, source, descr, discount_str, price_editable) {
593 var row = $('#item_' + item_id).parents("tbody").first();
594 var source_elt = $(row).find('[name="order.orderitems[].active_discount_source"]');
595 var button_elt = $(row).find('[name="price_chooser_button"]');
597 button_elt.val(button_elt.val().replace(/\|.*/, "| " + descr));
598 source_elt.val(source);
600 var editable_div_elt = $(row).find('[name="editable_discount"]');
601 var not_editable_div_elt = $(row).find('[name="not_editable_discount"]');
602 if (price_editable == 1 && source === '') {
604 $(editable_div_elt).show();
605 $(not_editable_div_elt).hide();
606 $(editable_div_elt).find(':input').prop("disabled", false);
607 $(not_editable_div_elt).find(':input').prop("disabled", true);
610 $(editable_div_elt).hide();
611 $(not_editable_div_elt).show();
612 $(editable_div_elt).find(':input').prop("disabled", true);
613 $(not_editable_div_elt).find(':input').prop("disabled", false);
617 var discount_elt = $(row).find('[name="order.orderitems[].discount_as_percent"]');
618 var html_elt = $(row).find('[name="discount_text"]');
619 discount_elt.val(discount_str);
620 html_elt.html(discount_str);
621 ns.recalc_amounts_and_taxes();
624 kivi.io.close_dialog();
627 ns.show_periodic_invoices_config_dialog = function() {
628 if ($('#type').val() !== 'sales_order') return;
631 url: 'controller.pl?action=Order/show_periodic_invoices_config_dialog',
632 data: { type: $('#type').val(),
634 config: $('#order_periodic_invoices_config').val(),
635 customer_id: $('#order_customer_id').val(),
636 transdate_as_date: $('#order_transdate_as_date').val(),
637 language_id: $('#language_id').val()
639 id: 'jq_periodic_invoices_config_dialog',
640 load: kivi.reinit_widgets,
642 title: kivi.t8('Edit the configuration for periodic invoices'),
650 ns.close_periodic_invoices_config_dialog = function() {
651 $('#jq_periodic_invoices_config_dialog').dialog('close');
654 ns.assign_periodic_invoices_config = function() {
655 var data = $('[name="Form"]').serializeArray();
656 data.push({ name: 'type', value: $('#type').val() },
657 { name: 'action', value: 'Order/assign_periodic_invoices_config' });
658 $.post("controller.pl", data, kivi.eval_json_result);
661 ns.check_save_active_periodic_invoices = function() {
662 var type = $('#type').val();
663 if (type !== 'sales_order') return true;
667 url: 'controller.pl',
668 data: { action: 'Order/get_has_active_periodic_invoices',
671 config: $('#order_periodic_invoices_config').val(),
676 success: function(val) {
682 return confirm(kivi.t8('This sales order has an active configuration for periodic invoices. If you save then all subsequently created invoices will contain those changes as well, but not those that have already been created. Do you want to continue?'));
688 ns.show_vc_details_dialog = function() {
689 if (!ns.check_cv()) return;
693 if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
695 vc_id = $('#order_customer_id').val();
696 title = kivi.t8('Customer details');
699 vc_id = $('#order_vendor_id').val();
700 title = kivi.t8('Vendor details');
704 url: 'controller.pl',
705 data: { action: 'Order/show_customer_vendor_details_dialog',
706 type : $('#type').val(),
710 id: 'jq_customer_vendor_details_dialog',
720 ns.update_row_from_master_data = function(clicked) {
721 var row = $(clicked).parents("tbody").first();
722 var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
724 var data = $('#order_form').serializeArray();
725 data.push({ name: 'action', value: 'Order/update_row_from_master_data' });
726 data.push({ name: 'item_ids[]', value: item_id_dom.val() });
728 $.post("controller.pl", data, kivi.eval_json_result);
731 ns.update_all_rows_from_master_data = function() {
732 var item_ids = $.map($('.row_entry'), function(elt) {
733 var item_id = $(elt).find('[name="orderitem_ids[+]"]').val();
734 return { name: 'item_ids[]', value: item_id };
737 if (item_ids.length == 0) {
741 var data = $('#order_form').serializeArray();
742 data.push({ name: 'action', value: 'Order/update_row_from_master_data' });
743 data = data.concat(item_ids);
745 $.post("controller.pl", data, kivi.eval_json_result);
748 ns.show_calculate_qty_dialog = function(clicked) {
749 var row = $(clicked).parents("tbody").first();
750 var input_id = $(row).find('[name="order.orderitems[].qty_as_number"]').attr('id');
751 var formula_id = $(row).find('[name="formula[+]"]').attr('id');
753 calculate_qty_selection_dialog("", input_id, "", formula_id);
760 if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
761 $('#order_customer_id').change(kivi.Order.reload_cv_dependant_selections);
763 $('#order_vendor_id').change(kivi.Order.reload_cv_dependant_selections);
766 if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
767 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_sellprice_as_number').val(kivi.format_amount(o.sellprice, -2)) });
769 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_sellprice_as_number').val(kivi.format_amount(o.lastcost, -2)) });
771 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_description').val(o.description) });
772 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_unit').val(o.unit) });
774 $('.add_item_input').keydown(function(event) {
775 if (event.keyCode == 13) {
776 event.preventDefault();
777 kivi.Order.add_item();
782 kivi.Order.init_row_handlers();
784 $('#row_table_id').on('sortstop', function(event, ui) {
785 $('#row_table_id thead a img').remove();
786 kivi.Order.renumber_positions();
789 $('#expand_all').on('click', function(event) {
790 event.preventDefault();
791 if ($('#expand_all').data('expanded') == 1) {
792 $('#expand_all').data('expanded', 0);
793 $('#expand_all').attr('src', 'image/expand.svg');
794 $('#expand_all').attr('alt', kivi.t8('Show all details'));
795 $('#expand_all').attr('title', kivi.t8('Show all details'));
796 $('.row_entry').each(function(idx, elt) {
797 kivi.Order.hide_second_row(elt);
800 $('#expand_all').data('expanded', 1);
801 $('#expand_all').attr('src', "image/collapse.svg");
802 $('#expand_all').attr('alt', kivi.t8('Hide all details'));
803 $('#expand_all').attr('title', kivi.t8('Hide all details'));
804 kivi.Order.load_all_second_rows();
805 $('.row_entry').each(function(idx, elt) {
806 kivi.Order.show_second_row(elt);