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.download_pdf = function(pdf_filename, key) {
91 var data = [{ name: 'action', value: 'Order/download_pdf' },
92 { name: 'type', value: $('#type').val() },
93 { name: 'pdf_filename', value: pdf_filename },
94 { name: 'key', value: key }];
95 $.download("controller.pl", data);
98 ns.email = function(warn_on_duplicates) {
99 if (warn_on_duplicates && !ns.check_duplicate_parts(kivi.t8("Do you really want to send by mail?"))) return;
100 if (!ns.check_cv()) return;
102 var data = $('#order_form').serializeArray();
103 data.push({ name: 'action', value: 'Order/show_email_dialog' });
105 $.post("controller.pl", data, kivi.eval_json_result);
110 ns.setup_send_email_dialog = function() {
111 kivi.SalesPurchase.show_all_print_options_elements();
112 kivi.SalesPurchase.show_print_options_elements([ 'sendmode', 'media', 'copies', 'remove_draft' ], false);
114 $('#print_options_form table').first().remove().appendTo('#email_form_print_options');
116 var to_focus = $('#email_form_to').val() === '' ? 'to' : 'subject';
117 $('#email_form_' + to_focus).focus();
120 ns.finish_send_email_dialog = function() {
121 kivi.SalesPurchase.show_all_print_options_elements();
123 $('#email_form_print_options table').first().remove().prependTo('#print_options_form');
127 ns.show_email_dialog = function(html) {
128 var id = 'send_email_dialog';
129 var dialog_params = {
133 title: kivi.t8('Send email'),
135 beforeClose: kivi.Order.finish_send_email_dialog,
136 close: function(event, ui) {
137 email_dialog.remove();
141 $('#' + id).remove();
143 email_dialog = $('<div style="display:none" id="' + id + '"></div>').appendTo('body');
144 email_dialog.html(html);
145 email_dialog.dialog(dialog_params);
147 kivi.Order.setup_send_email_dialog();
149 $('.cancel').click(ns.close_email_dialog);
154 ns.send_email = function() {
155 var data = $('#order_form').serializeArray();
156 data = data.concat($('[name^="email_form."]').serializeArray());
157 data = data.concat($('[name^="print_options."]').serializeArray());
158 data.push({ name: 'action', value: 'Order/send_email' });
159 $.post("controller.pl", data, kivi.eval_json_result);
162 ns.close_email_dialog = function() {
163 email_dialog.dialog("close");
166 ns.set_number_in_title = function(elt) {
167 $('#nr_in_title').html($(elt).val());
170 ns.reload_cv_dependant_selections = function() {
171 var data = $('#order_form').serializeArray();
172 data.push({ name: 'action', value: 'Order/customer_vendor_changed' });
174 $.post("controller.pl", data, kivi.eval_json_result);
177 ns.reformat_number = function(event) {
178 $(event.target).val(kivi.format_amount(kivi.parse_amount($(event.target).val()), -2));
181 ns.recalc_amounts_and_taxes = function() {
182 var data = $('#order_form').serializeArray();
183 data.push({ name: 'action', value: 'Order/recalc_amounts_and_taxes' });
185 $.post("controller.pl", data, kivi.eval_json_result);
188 ns.unit_change = function(event) {
189 var row = $(event.target).parents("tbody").first();
190 var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
191 var sellprice_dom = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
192 var select_elt = $(row).find('[name="order.orderitems[].unit"]');
194 var oldval = $(select_elt).data('oldval');
195 $(select_elt).data('oldval', $(select_elt).val());
197 var data = $('#order_form').serializeArray();
198 data.push({ name: 'action', value: 'Order/unit_changed' },
199 { name: 'item_id', value: item_id_dom.val() },
200 { name: 'old_unit', value: oldval },
201 { name: 'sellprice_dom_id', value: sellprice_dom.attr('id') });
203 $.post("controller.pl", data, kivi.eval_json_result);
206 ns.update_sellprice = function(item_id, price_str) {
207 var row = $('#item_' + item_id).parents("tbody").first();
208 var price_elt = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
209 var html_elt = $(row).find('[name="sellprice_text"]');
210 price_elt.val(price_str);
211 html_elt.html(price_str);
214 ns.load_second_row = function(row) {
215 var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
216 var div_elt = $(row).find('[name="second_row"]');
218 if ($(div_elt).data('loaded') == 1) {
221 var data = $('#order_form').serializeArray();
222 data.push({ name: 'action', value: 'Order/load_second_rows' },
223 { name: 'item_ids[]', value: item_id_dom.val() });
225 $.post("controller.pl", data, kivi.eval_json_result);
228 ns.load_all_second_rows = function() {
229 var rows = $('.row_entry').filter(function(idx, elt) {
230 return $(elt).find('[name="second_row"]').data('loaded') != 1;
233 var item_ids = $.map(rows, function(elt) {
234 var item_id = $(elt).find('[name="orderitem_ids[+]"]').val();
235 return { name: 'item_ids[]', value: item_id };
238 if (item_ids.length == 0) {
242 var data = $('#order_form').serializeArray();
243 data.push({ name: 'action', value: 'Order/load_second_rows' });
244 data = data.concat(item_ids);
246 $.post("controller.pl", data, kivi.eval_json_result);
249 ns.hide_second_row = function(row) {
250 $(row).children().not(':first').hide();
251 $(row).data('expanded', 0);
252 var elt = $(row).find('.expand');
253 elt.attr('src', "image/expand.svg");
254 elt.attr('alt', kivi.t8('Show details'));
255 elt.attr('title', kivi.t8('Show details'));
258 ns.show_second_row = function(row) {
259 $(row).children().not(':first').show();
260 $(row).data('expanded', 1);
261 var elt = $(row).find('.expand');
262 elt.attr('src', "image/collapse.svg");
263 elt.attr('alt', kivi.t8('Hide details'));
264 elt.attr('title', kivi.t8('Hide details'));
267 ns.toggle_second_row = function(row) {
268 if ($(row).data('expanded') == 1) {
269 ns.hide_second_row(row);
271 ns.show_second_row(row);
275 ns.init_row_handlers = function() {
276 kivi.run_once_for('.recalc', 'on_change_recalc', function(elt) {
277 $(elt).change(ns.recalc_amounts_and_taxes);
280 kivi.run_once_for('.reformat_number', 'on_change_reformat', function(elt) {
281 $(elt).change(ns.reformat_number);
284 kivi.run_once_for('.unitselect', 'on_change_unit_with_oldval', function(elt) {
285 $(elt).data('oldval', $(elt).val());
286 $(elt).change(ns.unit_change);
289 kivi.run_once_for('.row_entry', 'on_kbd_click_show_hide', function(elt) {
290 $(elt).keydown(function(event) {
292 if (event.keyCode == 40 && event.shiftKey === true) {
294 event.preventDefault();
295 row = $(event.target).parents(".row_entry").first();
296 ns.load_second_row(row);
297 ns.show_second_row(row);
300 if (event.keyCode == 38 && event.shiftKey === true) {
302 event.preventDefault();
303 row = $(event.target).parents(".row_entry").first();
304 ns.hide_second_row(row);
310 kivi.run_once_for('.expand', 'expand_second_row', function(elt) {
311 $(elt).click(function(event) {
312 event.preventDefault();
313 var row = $(event.target).parents(".row_entry").first();
314 ns.load_second_row(row);
315 ns.toggle_second_row(row);
322 ns.redisplay_line_values = function(is_sales, data) {
323 $('.row_entry').each(function(idx, elt) {
324 $(elt).find('[name="linetotal"]').html(data[idx][0]);
325 if (is_sales && $(elt).find('[name="second_row"]').data('loaded') == 1) {
326 var mt = data[idx][1];
327 var mp = data[idx][2];
329 if (mt[0] === '-') h += ' class="plus0"';
330 h += '>' + mt + ' ' + mp + '%';
332 $(elt).find('[name="linemargin"]').html(h);
337 ns.redisplay_cvpartnumbers = function(data) {
338 $('.row_entry').each(function(idx, elt) {
339 $(elt).find('[name="cvpartnumber"]').html(data[idx][0]);
343 ns.renumber_positions = function() {
344 $('.row_entry [name="position"]').each(function(idx, elt) {
349 ns.reorder_items = function(order_by) {
350 var dir = $('#' + order_by + '_header_id a img').attr("data-sort-dir");
351 $('#row_table_id thead a img').remove();
356 src = "image/up.png";
359 src = "image/down.png";
362 $('#' + order_by + '_header_id a').append('<img border=0 data-sort-dir=' + dir + ' src=' + src + ' alt="' + kivi.t8('sort items') + '">');
364 var data = $('#order_form').serializeArray();
365 data.push({ name: 'action', value: 'Order/reorder_items' },
366 { name: 'order_by', value: order_by },
367 { name: 'sort_dir', value: dir });
369 $.post("controller.pl", data, kivi.eval_json_result);
372 ns.redisplay_items = function(data) {
373 var old_rows = $('.row_entry').detach();
375 $(data).each(function(idx, elt) {
376 new_rows.push(old_rows[elt.old_pos - 1]);
378 $(new_rows).appendTo($('#row_table_id'));
379 ns.renumber_positions();
382 ns.add_item = function() {
383 if ($('#add_item_parts_id').val() === '') return;
384 if (!ns.check_cv()) return;
386 $('#row_table_id thead a img').remove();
388 var data = $('#order_form').serializeArray();
389 data.push({ name: 'action', value: 'Order/add_item' });
391 $.post("controller.pl", data, kivi.eval_json_result);
394 ns.setup_multi_items_dialog = function() {
395 $('#multi_items_filter_table input, #multi_items_filter_table select').keydown(function(event) {
396 if (event.keyCode == 13) {
397 event.preventDefault();
398 ns.multi_items_dialog_update_result();
403 $('#multi_items_filter_all_substr_multi_ilike').focus();
406 ns.show_multi_items_dialog = function() {
407 if (!ns.check_cv()) return;
409 $('#row_table_id thead a img').remove();
412 url: 'controller.pl?action=Order/show_multi_items_dialog',
413 data: { type: $('#type').val() },
414 id: 'jq_multi_items_dialog',
415 load: kivi.Order.setup_multi_items_dialog,
417 title: kivi.t8('Add multiple items'),
425 ns.close_multi_items_dialog = function() {
426 $('#jq_multi_items_dialog').dialog('close');
429 ns.multi_items_dialog_update_result = function() {
430 var data = $('#multi_items_form').serializeArray();
431 data.push({ name: 'type', value: $('#type').val() });
433 url: 'controller.pl?action=Order/multi_items_update_result',
436 success: function(data) {
437 $('#multi_items_result').html(data);
438 ns.multi_items_dialog_enable_continue();
439 ns.multi_items_result_setup_events();
444 ns.multi_items_dialog_disable_continue = function() {
445 // disable keydown-event and continue button to prevent
446 // impatient users to add parts multiple times
447 $('#multi_items_result input').off("keydown");
448 $('#multi_items_dialog_continue_button').prop('disabled', true);
451 ns.multi_items_dialog_enable_continue = function() {
452 $('#multi_items_result input').keydown(function(event) {
453 if(event.keyCode == 13) {
454 event.preventDefault();
455 ns.add_multi_items();
459 $('#multi_items_dialog_continue_button').prop('disabled', false);
462 ns.multi_items_result_setup_events = function() {
463 $('#multi_items_all_qty').change(ns.reformat_number);
464 $('#multi_items_all_qty').change(function(event) {
465 $('.multi_items_qty').val($(event.target).val());
467 $('.multi_items_qty').change(ns.reformat_number);
470 ns.add_multi_items = function() {
472 var n_rows = $('.multi_items_qty').length;
473 if (n_rows == 0) return;
476 n_rows = $('.multi_items_qty').filter(function() {
477 return $(this).val().length > 0;
479 if (n_rows == 0) return;
481 ns.multi_items_dialog_disable_continue();
483 var data = $('#order_form').serializeArray();
484 data = data.concat($('#multi_items_form').serializeArray());
485 data.push({ name: 'action', value: 'Order/add_multi_items' });
486 $.post("controller.pl", data, kivi.eval_json_result);
489 ns.set_input_to_one = function(clicked) {
490 if ($(clicked).val() == '') {
491 $(clicked).val(kivi.format_amount(1.00, -2));
496 ns.delete_order_item_row = function(clicked) {
497 var row = $(clicked).parents("tbody").first();
500 ns.renumber_positions();
501 ns.recalc_amounts_and_taxes();
504 ns.row_table_scroll_down = function() {
505 $('#row_table_scroll_id').scrollTop($('#row_table_scroll_id')[0].scrollHeight);
508 ns.show_longdescription_dialog = function(clicked) {
509 var row = $(clicked).parents("tbody").first();
510 var position = $(row).find('[name="position"]').html();
511 var partnumber = $(row).find('[name="partnumber"]').html();
512 var description_elt = $(row).find('[name="order.orderitems[].description"]');
513 var description = description_elt.val();
514 var longdescription_elt = $(row).find('[name="order.orderitems[].longdescription"]');
517 if (!longdescription_elt.length) {
519 { name: 'action', value: 'Order/get_item_longdescription' },
520 { name: 'type', value: $('#type').val() },
521 { name: 'item_id', value: $(row).find('[name="order.orderitems[+].id"]').val() },
522 { name: 'parts_id', value: $(row).find('[name="order.orderitems[].parts_id"]').val() }
526 url: 'controller.pl',
531 success: function(val) {
532 longdescription = val;
536 longdescription = longdescription_elt.val();
540 runningnumber: position,
541 partnumber: partnumber,
542 description: description,
543 default_longdescription: longdescription,
544 set_function: function(val) {
545 longdescription_elt.remove();
546 $('<input type="hidden" name="order.orderitems[].longdescription">').insertAfter(description_elt).val(val);
550 kivi.SalesPurchase.edit_longdescription_with_params(params);
553 ns.price_chooser_item_row = function(clicked) {
554 if (!ns.check_cv()) return;
555 var row = $(clicked).parents("tbody").first();
556 var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
558 var data = $('#order_form').serializeArray();
559 data.push({ name: 'action', value: 'Order/price_popup' },
560 { name: 'item_id', value: item_id_dom.val() });
562 $.post("controller.pl", data, kivi.eval_json_result);
565 ns.update_price_source = function(item_id, source, descr, price_str, price_editable) {
566 var row = $('#item_' + item_id).parents("tbody").first();
567 var source_elt = $(row).find('[name="order.orderitems[].active_price_source"]');
568 var button_elt = $(row).find('[name="price_chooser_button"]');
570 button_elt.val(button_elt.val().replace(/.*\|/, descr + " |"));
571 source_elt.val(source);
573 var editable_div_elt = $(row).find('[name="editable_price"]');
574 var not_editable_div_elt = $(row).find('[name="not_editable_price"]');
575 if (price_editable == 1 && source === '') {
577 $(editable_div_elt).show();
578 $(not_editable_div_elt).hide();
579 $(editable_div_elt).find(':input').prop("disabled", false);
580 $(not_editable_div_elt).find(':input').prop("disabled", true);
583 $(editable_div_elt).hide();
584 $(not_editable_div_elt).show();
585 $(editable_div_elt).find(':input').prop("disabled", true);
586 $(not_editable_div_elt).find(':input').prop("disabled", false);
590 var price_elt = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
591 var html_elt = $(row).find('[name="sellprice_text"]');
592 price_elt.val(price_str);
593 html_elt.html(price_str);
594 ns.recalc_amounts_and_taxes();
597 kivi.io.close_dialog();
600 ns.update_discount_source = function(item_id, source, descr, discount_str, price_editable) {
601 var row = $('#item_' + item_id).parents("tbody").first();
602 var source_elt = $(row).find('[name="order.orderitems[].active_discount_source"]');
603 var button_elt = $(row).find('[name="price_chooser_button"]');
605 button_elt.val(button_elt.val().replace(/\|.*/, "| " + descr));
606 source_elt.val(source);
608 var editable_div_elt = $(row).find('[name="editable_discount"]');
609 var not_editable_div_elt = $(row).find('[name="not_editable_discount"]');
610 if (price_editable == 1 && source === '') {
612 $(editable_div_elt).show();
613 $(not_editable_div_elt).hide();
614 $(editable_div_elt).find(':input').prop("disabled", false);
615 $(not_editable_div_elt).find(':input').prop("disabled", true);
618 $(editable_div_elt).hide();
619 $(not_editable_div_elt).show();
620 $(editable_div_elt).find(':input').prop("disabled", true);
621 $(not_editable_div_elt).find(':input').prop("disabled", false);
625 var discount_elt = $(row).find('[name="order.orderitems[].discount_as_percent"]');
626 var html_elt = $(row).find('[name="discount_text"]');
627 discount_elt.val(discount_str);
628 html_elt.html(discount_str);
629 ns.recalc_amounts_and_taxes();
632 kivi.io.close_dialog();
635 ns.show_periodic_invoices_config_dialog = function() {
636 if ($('#type').val() !== 'sales_order') return;
639 url: 'controller.pl?action=Order/show_periodic_invoices_config_dialog',
640 data: { type: $('#type').val(),
642 config: $('#order_periodic_invoices_config').val(),
643 customer_id: $('#order_customer_id').val(),
644 transdate_as_date: $('#order_transdate_as_date').val(),
645 language_id: $('#language_id').val()
647 id: 'jq_periodic_invoices_config_dialog',
648 load: kivi.reinit_widgets,
650 title: kivi.t8('Edit the configuration for periodic invoices'),
658 ns.close_periodic_invoices_config_dialog = function() {
659 $('#jq_periodic_invoices_config_dialog').dialog('close');
662 ns.assign_periodic_invoices_config = function() {
663 var data = $('[name="Form"]').serializeArray();
664 data.push({ name: 'type', value: $('#type').val() },
665 { name: 'action', value: 'Order/assign_periodic_invoices_config' });
666 $.post("controller.pl", data, kivi.eval_json_result);
669 ns.check_save_active_periodic_invoices = function() {
670 var type = $('#type').val();
671 if (type !== 'sales_order') return true;
675 url: 'controller.pl',
676 data: { action: 'Order/get_has_active_periodic_invoices',
679 config: $('#order_periodic_invoices_config').val(),
684 success: function(val) {
690 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?'));
696 ns.show_vc_details_dialog = function() {
697 if (!ns.check_cv()) return;
701 if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
703 vc_id = $('#order_customer_id').val();
704 title = kivi.t8('Customer details');
707 vc_id = $('#order_vendor_id').val();
708 title = kivi.t8('Vendor details');
712 url: 'controller.pl',
713 data: { action: 'Order/show_customer_vendor_details_dialog',
714 type : $('#type').val(),
718 id: 'jq_customer_vendor_details_dialog',
728 ns.show_calculate_qty_dialog = function(clicked) {
729 var row = $(clicked).parents("tbody").first();
730 var input_id = $(row).find('[name="order.orderitems[].qty_as_number"]').attr('id');
731 var formula_id = $(row).find('[name="formula[+]"]').attr('id');
733 calculate_qty_selection_dialog("", input_id, "", formula_id);
740 if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
741 $('#order_customer_id').change(kivi.Order.reload_cv_dependant_selections);
743 $('#order_vendor_id').change(kivi.Order.reload_cv_dependant_selections);
746 if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
747 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_sellprice_as_number').val(kivi.format_amount(o.sellprice, -2)) });
749 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_sellprice_as_number').val(kivi.format_amount(o.lastcost, -2)) });
751 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_description').val(o.description) });
752 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_unit').val(o.unit) });
754 $('.add_item_input').keydown(function(event) {
755 if (event.keyCode == 13) {
756 event.preventDefault();
757 kivi.Order.add_item();
762 kivi.Order.init_row_handlers();
764 $('#row_table_id').on('sortstop', function(event, ui) {
765 $('#row_table_id thead a img').remove();
766 kivi.Order.renumber_positions();
769 $('#expand_all').on('click', function(event) {
770 event.preventDefault();
771 if ($('#expand_all').data('expanded') == 1) {
772 $('#expand_all').data('expanded', 0);
773 $('#expand_all').attr('src', 'image/expand.svg');
774 $('#expand_all').attr('alt', kivi.t8('Show all details'));
775 $('#expand_all').attr('title', kivi.t8('Show all details'));
776 $('.row_entry').each(function(idx, elt) {
777 kivi.Order.hide_second_row(elt);
780 $('#expand_all').data('expanded', 1);
781 $('#expand_all').attr('src', "image/collapse.svg");
782 $('#expand_all').attr('alt', kivi.t8('Hide all details'));
783 $('#expand_all').attr('title', kivi.t8('Hide all details'));
784 kivi.Order.load_all_second_rows();
785 $('.row_entry').each(function(idx, elt) {
786 kivi.Order.show_second_row(elt);