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_save_duplicate_parts = function() {
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 return confirm(kivi.t8("There are duplicate parts at positions") + "\n"
32 + pos.join(', ') + "\n"
33 + kivi.t8("Do you really want to save?"));
38 ns.check_valid_reqdate = function() {
39 if ($('#order_reqdate').val() === '') {
40 alert(kivi.t8('Please select a delivery date.'));
47 ns.save = function(action, warn_on_duplicates, warn_on_reqdate) {
48 if (!ns.check_cv()) return;
49 if (warn_on_duplicates && !ns.check_save_duplicate_parts()) return;
50 if (warn_on_reqdate && !ns.check_valid_reqdate()) return;
52 var data = $('#order_form').serializeArray();
53 data.push({ name: 'action', value: 'Order/' + action });
55 $.post("controller.pl", data, kivi.eval_json_result);
58 ns.delete_order = function() {
59 var data = $('#order_form').serializeArray();
60 data.push({ name: 'action', value: 'Order/delete' });
62 $.post("controller.pl", data, kivi.eval_json_result);
65 ns.show_print_options = function() {
66 if (!ns.check_cv()) return;
71 title: kivi.t8('Print options'),
78 ns.print = function() {
79 $('#print_options').dialog('close');
81 var data = $('#order_form').serializeArray();
82 data = data.concat($('#print_options_form').serializeArray());
83 data.push({ name: 'action', value: 'Order/print' });
85 $.post("controller.pl", data, kivi.eval_json_result);
88 ns.download_pdf = function(pdf_filename, key) {
89 var data = [{ name: 'action', value: 'Order/download_pdf' },
90 { name: 'type', value: $('#type').val() },
91 { name: 'pdf_filename', value: pdf_filename },
92 { name: 'key', value: key }];
93 $.download("controller.pl", data);
96 ns.email = function() {
97 if (!ns.check_cv()) return;
98 var data = $('#order_form').serializeArray();
99 data.push({ name: 'action', value: 'Order/show_email_dialog' });
101 $.post("controller.pl", data, kivi.eval_json_result);
106 ns.setup_send_email_dialog = function() {
107 kivi.SalesPurchase.show_all_print_options_elements();
108 kivi.SalesPurchase.show_print_options_elements([ 'sendmode', 'media', 'copies', 'remove_draft' ], false);
110 $('#print_options_form table').first().remove().appendTo('#email_form_print_options');
112 var to_focus = $('#email_form_to').val() === '' ? 'to' : 'subject';
113 $('#email_form_' + to_focus).focus();
116 ns.finish_send_email_dialog = function() {
117 kivi.SalesPurchase.show_all_print_options_elements();
119 $('#email_form_print_options table').first().remove().prependTo('#print_options_form');
123 ns.show_email_dialog = function(html) {
124 var id = 'send_email_dialog';
125 var dialog_params = {
129 title: kivi.t8('Send email'),
131 beforeClose: kivi.Order.finish_send_email_dialog,
132 close: function(event, ui) {
133 email_dialog.remove();
137 $('#' + id).remove();
139 email_dialog = $('<div style="display:none" id="' + id + '"></div>').appendTo('body');
140 email_dialog.html(html);
141 email_dialog.dialog(dialog_params);
143 kivi.Order.setup_send_email_dialog();
145 $('.cancel').click(ns.close_email_dialog);
150 ns.send_email = function() {
151 var data = $('#order_form').serializeArray();
152 data = data.concat($('[name^="email_form."]').serializeArray());
153 data = data.concat($('[name^="print_options."]').serializeArray());
154 data.push({ name: 'action', value: 'Order/send_email' });
155 $.post("controller.pl", data, kivi.eval_json_result);
158 ns.close_email_dialog = function() {
159 email_dialog.dialog("close");
162 ns.set_number_in_title = function(elt) {
163 $('#nr_in_title').html($(elt).val());
166 ns.reload_cv_dependant_selections = function() {
167 var data = $('#order_form').serializeArray();
168 data.push({ name: 'action', value: 'Order/customer_vendor_changed' });
170 $.post("controller.pl", data, kivi.eval_json_result);
173 ns.reformat_number = function(event) {
174 $(event.target).val(kivi.format_amount(kivi.parse_amount($(event.target).val()), -2));
177 ns.recalc_amounts_and_taxes = function() {
178 var data = $('#order_form').serializeArray();
179 data.push({ name: 'action', value: 'Order/recalc_amounts_and_taxes' });
181 $.post("controller.pl", data, kivi.eval_json_result);
184 ns.unit_change = function(event) {
185 var row = $(event.target).parents("tbody").first();
186 var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
187 var sellprice_dom = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
188 var select_elt = $(row).find('[name="order.orderitems[].unit"]');
190 var oldval = $(select_elt).data('oldval');
191 $(select_elt).data('oldval', $(select_elt).val());
193 var data = $('#order_form').serializeArray();
194 data.push({ name: 'action', value: 'Order/unit_changed' },
195 { name: 'item_id', value: item_id_dom.val() },
196 { name: 'old_unit', value: oldval },
197 { name: 'sellprice_dom_id', value: sellprice_dom.attr('id') });
199 $.post("controller.pl", data, kivi.eval_json_result);
202 ns.update_sellprice = function(item_id, price_str) {
203 var row = $('#item_' + item_id).parents("tbody").first();
204 var price_elt = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
205 var html_elt = $(row).find('[name="sellprice_text"]');
206 price_elt.val(price_str);
207 html_elt.html(price_str);
210 ns.load_second_row = function(row) {
211 var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
212 var div_elt = $(row).find('[name="second_row"]');
214 if ($(div_elt).data('loaded') == 1) {
217 var data = $('#order_form').serializeArray();
218 data.push({ name: 'action', value: 'Order/load_second_rows' },
219 { name: 'item_ids[]', value: item_id_dom.val() });
221 $.post("controller.pl", data, kivi.eval_json_result);
224 ns.load_all_second_rows = function() {
225 var rows = $('.row_entry').filter(function(idx, elt) {
226 return $(elt).find('[name="second_row"]').data('loaded') != 1;
229 var item_ids = $.map(rows, function(elt) {
230 var item_id = $(elt).find('[name="orderitem_ids[+]"]').val();
231 return { name: 'item_ids[]', value: item_id };
234 if (item_ids.length == 0) {
238 var data = $('#order_form').serializeArray();
239 data.push({ name: 'action', value: 'Order/load_second_rows' });
240 data = data.concat(item_ids);
242 $.post("controller.pl", data, kivi.eval_json_result);
245 ns.hide_second_row = function(row) {
246 $(row).children().not(':first').hide();
247 $(row).data('expanded', 0);
248 var elt = $(row).find('.expand');
249 elt.attr('src', "image/expand.svg");
250 elt.attr('alt', kivi.t8('Show details'));
251 elt.attr('title', kivi.t8('Show details'));
254 ns.show_second_row = function(row) {
255 $(row).children().not(':first').show();
256 $(row).data('expanded', 1);
257 var elt = $(row).find('.expand');
258 elt.attr('src', "image/collapse.svg");
259 elt.attr('alt', kivi.t8('Hide details'));
260 elt.attr('title', kivi.t8('Hide details'));
263 ns.toggle_second_row = function(row) {
264 if ($(row).data('expanded') == 1) {
265 ns.hide_second_row(row);
267 ns.show_second_row(row);
271 ns.init_row_handlers = function() {
272 kivi.run_once_for('.recalc', 'on_change_recalc', function(elt) {
273 $(elt).change(ns.recalc_amounts_and_taxes);
276 kivi.run_once_for('.reformat_number', 'on_change_reformat', function(elt) {
277 $(elt).change(ns.reformat_number);
280 kivi.run_once_for('.unitselect', 'on_change_unit_with_oldval', function(elt) {
281 $(elt).data('oldval', $(elt).val());
282 $(elt).change(ns.unit_change);
285 kivi.run_once_for('.row_entry', 'on_kbd_click_show_hide', function(elt) {
286 $(elt).keydown(function(event) {
288 if (event.keyCode == 40 && event.shiftKey === true) {
290 event.preventDefault();
291 row = $(event.target).parents(".row_entry").first();
292 ns.load_second_row(row);
293 ns.show_second_row(row);
296 if (event.keyCode == 38 && event.shiftKey === true) {
298 event.preventDefault();
299 row = $(event.target).parents(".row_entry").first();
300 ns.hide_second_row(row);
306 kivi.run_once_for('.expand', 'expand_second_row', function(elt) {
307 $(elt).click(function(event) {
308 event.preventDefault();
309 var row = $(event.target).parents(".row_entry").first();
310 ns.load_second_row(row);
311 ns.toggle_second_row(row);
318 ns.redisplay_line_values = function(is_sales, data) {
319 $('.row_entry').each(function(idx, elt) {
320 $(elt).find('[name="linetotal"]').html(data[idx][0]);
321 if (is_sales && $(elt).find('[name="second_row"]').data('loaded') == 1) {
322 var mt = data[idx][1];
323 var mp = data[idx][2];
325 if (mt[0] === '-') h += ' class="plus0"';
326 h += '>' + mt + ' ' + mp + '%';
328 $(elt).find('[name="linemargin"]').html(h);
333 ns.renumber_positions = function() {
334 $('.row_entry [name="position"]').each(function(idx, elt) {
339 ns.reorder_items = function(order_by) {
340 var dir = $('#' + order_by + '_header_id a img').attr("data-sort-dir");
341 $('#row_table_id thead a img').remove();
346 src = "image/up.png";
349 src = "image/down.png";
352 $('#' + order_by + '_header_id a').append('<img border=0 data-sort-dir=' + dir + ' src=' + src + ' alt="' + kivi.t8('sort items') + '">');
354 var data = $('#order_form').serializeArray();
355 data.push({ name: 'action', value: 'Order/reorder_items' },
356 { name: 'order_by', value: order_by },
357 { name: 'sort_dir', value: dir });
359 $.post("controller.pl", data, kivi.eval_json_result);
362 ns.redisplay_items = function(data) {
363 var old_rows = $('.row_entry').detach();
365 $(data).each(function(idx, elt) {
366 new_rows.push(old_rows[elt.old_pos - 1]);
368 $(new_rows).appendTo($('#row_table_id'));
369 ns.renumber_positions();
372 ns.add_item = function() {
373 if ($('#add_item_parts_id').val() === '') return;
374 if (!ns.check_cv()) return;
376 $('#row_table_id thead a img').remove();
378 var data = $('#order_form').serializeArray();
379 data.push({ name: 'action', value: 'Order/add_item' });
381 $.post("controller.pl", data, kivi.eval_json_result);
384 ns.setup_multi_items_dialog = function() {
385 $('#multi_items_filter_table input, #multi_items_filter_table select').keydown(function(event) {
386 if (event.keyCode == 13) {
387 event.preventDefault();
388 ns.multi_items_dialog_update_result();
393 $('#multi_items_filter_all_substr_multi_ilike').focus();
396 ns.show_multi_items_dialog = function() {
397 if (!ns.check_cv()) return;
399 $('#row_table_id thead a img').remove();
402 url: 'controller.pl?action=Order/show_multi_items_dialog',
403 data: { type: $('#type').val() },
404 id: 'jq_multi_items_dialog',
405 load: kivi.Order.setup_multi_items_dialog,
407 title: kivi.t8('Add multiple items'),
415 ns.close_multi_items_dialog = function() {
416 $('#jq_multi_items_dialog').dialog('close');
419 ns.multi_items_dialog_update_result = function() {
420 var data = $('#multi_items_form').serializeArray();
421 data.push({ name: 'type', value: $('#type').val() });
423 url: 'controller.pl?action=Order/multi_items_update_result',
426 success: function(data) {
427 $('#multi_items_result').html(data);
428 ns.multi_items_dialog_enable_continue();
429 ns.multi_items_result_setup_events();
434 ns.multi_items_dialog_disable_continue = function() {
435 // disable keydown-event and continue button to prevent
436 // impatient users to add parts multiple times
437 $('#multi_items_result input').off("keydown");
438 $('#multi_items_dialog_continue_button').prop('disabled', true);
441 ns.multi_items_dialog_enable_continue = function() {
442 $('#multi_items_result input').keydown(function(event) {
443 if(event.keyCode == 13) {
444 event.preventDefault();
445 ns.add_multi_items();
449 $('#multi_items_dialog_continue_button').prop('disabled', false);
452 ns.multi_items_result_setup_events = function() {
453 $('#multi_items_all_qty').change(ns.reformat_number);
454 $('#multi_items_all_qty').change(function(event) {
455 $('.multi_items_qty').val($(event.target).val());
457 $('.multi_items_qty').change(ns.reformat_number);
460 ns.add_multi_items = function() {
462 var n_rows = $('.multi_items_qty').length;
463 if (n_rows == 0) return;
466 n_rows = $('.multi_items_qty').filter(function() {
467 return $(this).val().length > 0;
469 if (n_rows == 0) return;
471 ns.multi_items_dialog_disable_continue();
473 var data = $('#order_form').serializeArray();
474 data = data.concat($('#multi_items_form').serializeArray());
475 data.push({ name: 'action', value: 'Order/add_multi_items' });
476 $.post("controller.pl", data, kivi.eval_json_result);
479 ns.set_input_to_one = function(clicked) {
480 if ($(clicked).val() == '') {
481 $(clicked).val(kivi.format_amount(1.00, -2));
486 ns.delete_order_item_row = function(clicked) {
487 var row = $(clicked).parents("tbody").first();
490 ns.renumber_positions();
491 ns.recalc_amounts_and_taxes();
494 ns.row_table_scroll_down = function() {
495 $('#row_table_scroll_id').scrollTop($('#row_table_scroll_id')[0].scrollHeight);
498 ns.show_longdescription_dialog = function(clicked) {
499 var row = $(clicked).parents("tbody").first();
500 var position = $(row).find('[name="position"]').html();
501 var partnumber = $(row).find('[name="partnumber"]').html();
502 var description_elt = $(row).find('[name="order.orderitems[].description"]');
503 var description = description_elt.val();
504 var longdescription_elt = $(row).find('[name="order.orderitems[].longdescription"]');
507 if (!longdescription_elt.length) {
509 { name: 'action', value: 'Order/get_item_longdescription' },
510 { name: 'type', value: $('#type').val() },
511 { name: 'item_id', value: $(row).find('[name="order.orderitems[+].id"]').val() },
512 { name: 'parts_id', value: $(row).find('[name="order.orderitems[].parts_id"]').val() }
516 url: 'controller.pl',
521 success: function(val) {
522 longdescription = val;
526 longdescription = longdescription_elt.val();
530 runningnumber: position,
531 partnumber: partnumber,
532 description: description,
533 default_longdescription: longdescription,
534 set_function: function(val) {
535 longdescription_elt.remove();
536 $('<input type="hidden" name="order.orderitems[].longdescription">').insertAfter(description_elt).val(val);
540 kivi.SalesPurchase.edit_longdescription_with_params(params);
543 ns.price_chooser_item_row = function(clicked) {
544 if (!ns.check_cv()) return;
545 var row = $(clicked).parents("tbody").first();
546 var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
548 var data = $('#order_form').serializeArray();
549 data.push({ name: 'action', value: 'Order/price_popup' },
550 { name: 'item_id', value: item_id_dom.val() });
552 $.post("controller.pl", data, kivi.eval_json_result);
555 ns.update_price_source = function(item_id, source, descr, price_str, price_editable) {
556 var row = $('#item_' + item_id).parents("tbody").first();
557 var source_elt = $(row).find('[name="order.orderitems[].active_price_source"]');
558 var button_elt = $(row).find('[name="price_chooser_button"]');
560 button_elt.val(button_elt.val().replace(/.*\|/, descr + " |"));
561 source_elt.val(source);
563 var editable_div_elt = $(row).find('[name="editable_price"]');
564 var not_editable_div_elt = $(row).find('[name="not_editable_price"]');
565 if (price_editable == 1 && source === '') {
567 $(editable_div_elt).show();
568 $(not_editable_div_elt).hide();
569 $(editable_div_elt).find(':input').prop("disabled", false);
570 $(not_editable_div_elt).find(':input').prop("disabled", true);
573 $(editable_div_elt).hide();
574 $(not_editable_div_elt).show();
575 $(editable_div_elt).find(':input').prop("disabled", true);
576 $(not_editable_div_elt).find(':input').prop("disabled", false);
580 var price_elt = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
581 var html_elt = $(row).find('[name="sellprice_text"]');
582 price_elt.val(price_str);
583 html_elt.html(price_str);
584 ns.recalc_amounts_and_taxes();
587 kivi.io.close_dialog();
590 ns.update_discount_source = function(item_id, source, descr, discount_str, price_editable) {
591 var row = $('#item_' + item_id).parents("tbody").first();
592 var source_elt = $(row).find('[name="order.orderitems[].active_discount_source"]');
593 var button_elt = $(row).find('[name="price_chooser_button"]');
595 button_elt.val(button_elt.val().replace(/\|.*/, "| " + descr));
596 source_elt.val(source);
598 var editable_div_elt = $(row).find('[name="editable_discount"]');
599 var not_editable_div_elt = $(row).find('[name="not_editable_discount"]');
600 if (price_editable == 1 && source === '') {
602 $(editable_div_elt).show();
603 $(not_editable_div_elt).hide();
604 $(editable_div_elt).find(':input').prop("disabled", false);
605 $(not_editable_div_elt).find(':input').prop("disabled", true);
608 $(editable_div_elt).hide();
609 $(not_editable_div_elt).show();
610 $(editable_div_elt).find(':input').prop("disabled", true);
611 $(not_editable_div_elt).find(':input').prop("disabled", false);
615 var discount_elt = $(row).find('[name="order.orderitems[].discount_as_percent"]');
616 var html_elt = $(row).find('[name="discount_text"]');
617 discount_elt.val(discount_str);
618 html_elt.html(discount_str);
619 ns.recalc_amounts_and_taxes();
622 kivi.io.close_dialog();
625 ns.show_periodic_invoices_config_dialog = function() {
626 if ($('#type').val() !== 'sales_order') return;
629 url: 'controller.pl?action=Order/show_periodic_invoices_config_dialog',
630 data: { type: $('#type').val(),
632 config: $('#order_periodic_invoices_config').val(),
633 customer_id: $('#order_customer_id').val(),
634 transdate: $('#order_transdate').val(),
635 language_id: $('#language_id').val()
637 id: 'jq_periodic_invoices_config_dialog',
638 load: kivi.reinit_widgets,
640 title: kivi.t8('Edit the configuration for periodic invoices'),
648 ns.close_periodic_invoices_config_dialog = function() {
649 $('#jq_periodic_invoices_config_dialog').dialog('close');
652 ns.assign_periodic_invoices_config = function() {
653 var data = $('[name="Form"]').serializeArray();
654 data.push({ name: 'type', value: $('#type').val() },
655 { name: 'action', value: 'Order/assign_periodic_invoices_config' });
656 $.post("controller.pl", data, kivi.eval_json_result);
659 ns.check_save_active_periodic_invoices = function() {
660 var type = $('#type').val();
661 if (type !== 'sales_order') return true;
665 url: 'controller.pl',
666 data: { action: 'Order/get_has_active_periodic_invoices',
669 config: $('#order_periodic_invoices_config').val(),
674 success: function(val) {
680 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?'));
686 ns.show_vc_details_dialog = function() {
687 if (!ns.check_cv()) return;
691 if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
693 vc_id = $('#order_customer_id').val();
694 title = kivi.t8('Customer details');
697 vc_id = $('#order_vendor_id').val();
698 title = kivi.t8('Vendor details');
702 url: 'controller.pl',
703 data: { action: 'Order/show_customer_vendor_details_dialog',
704 type : $('#type').val(),
708 id: 'jq_customer_vendor_details_dialog',
718 ns.show_calculate_qty_dialog = function(clicked) {
719 var row = $(clicked).parents("tbody").first();
720 var input_id = $(row).find('[name="order.orderitems[].qty_as_number"]').attr('id');
721 var formula_id = $(row).find('[name="formula[+]"]').attr('id');
723 calculate_qty_selection_dialog("", input_id, "", formula_id);
730 if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
731 $('#order_customer_id').change(kivi.Order.reload_cv_dependant_selections);
733 $('#order_vendor_id').change(kivi.Order.reload_cv_dependant_selections);
736 if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
737 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_sellprice_as_number').val(kivi.format_amount(o.sellprice, -2)) });
739 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_sellprice_as_number').val(kivi.format_amount(o.lastcost, -2)) });
741 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_description').val(o.description) });
742 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_unit').val(o.unit) });
744 $('.add_item_input').keydown(function(event) {
745 if (event.keyCode == 13) {
746 event.preventDefault();
747 kivi.Order.add_item();
752 kivi.Order.init_row_handlers();
754 $('#row_table_id').on('sortstop', function(event, ui) {
755 $('#row_table_id thead a img').remove();
756 kivi.Order.renumber_positions();
759 $('#expand_all').on('click', function(event) {
760 event.preventDefault();
761 if ($('#expand_all').data('expanded') == 1) {
762 $('#expand_all').data('expanded', 0);
763 $('#expand_all').attr('src', 'image/expand.svg');
764 $('#expand_all').attr('alt', kivi.t8('Show all details'));
765 $('#expand_all').attr('title', kivi.t8('Show all details'));
766 $('.row_entry').each(function(idx, elt) {
767 kivi.Order.hide_second_row(elt);
770 $('#expand_all').data('expanded', 1);
771 $('#expand_all').attr('src', "image/collapse.svg");
772 $('#expand_all').attr('alt', kivi.t8('Hide all details'));
773 $('#expand_all').attr('title', kivi.t8('Hide all details'));
774 kivi.Order.load_all_second_rows();
775 $('.row_entry').each(function(idx, elt) {
776 kivi.Order.show_second_row(elt);