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: 'order.language_id', value: $('#language_id').val() }); // language from print options
 
  55     data.push({ name: 'action', value: 'Order/' + action });
 
  57     $.post("controller.pl", data, kivi.eval_json_result);
 
  60   ns.delete_order = function() {
 
  61     var data = $('#order_form').serializeArray();
 
  62     data.push({ name: 'action', value: 'Order/delete' });
 
  64     $.post("controller.pl", data, kivi.eval_json_result);
 
  67   ns.show_print_options = function(warn_on_duplicates) {
 
  68     if (!ns.check_cv()) return;
 
  69     if (warn_on_duplicates && !ns.check_duplicate_parts(kivi.t8("Do you really want to print?"))) return;
 
  74         title: kivi.t8('Print options'),
 
  81   ns.print = function() {
 
  82     $('#print_options').dialog('close');
 
  84     var data = $('#order_form').serializeArray();
 
  85     data = data.concat($('#print_options_form').serializeArray());
 
  86     data.push({ name: 'order.language_id', value: $('#language_id').val() }); // language from print options
 
  87     data.push({ name: 'action', value: 'Order/print' });
 
  89     $.post("controller.pl", data, kivi.eval_json_result);
 
  92   ns.email = function(warn_on_duplicates) {
 
  93     if (warn_on_duplicates && !ns.check_duplicate_parts(kivi.t8("Do you really want to send by mail?"))) return;
 
  94     if (!ns.check_cv()) return;
 
  96     var data = $('#order_form').serializeArray();
 
  97     data.push({ name: 'order.language_id', value: $('#language_id').val() }); // language from print options
 
  98     data.push({ name: 'action', value: 'Order/show_email_dialog' });
 
 100     $.post("controller.pl", data, kivi.eval_json_result);
 
 105   ns.setup_send_email_dialog = function() {
 
 106     kivi.SalesPurchase.show_all_print_options_elements();
 
 107     kivi.SalesPurchase.show_print_options_elements([ 'sendmode', 'media', 'copies', 'remove_draft' ], false);
 
 109     $('#print_options_form table').first().remove().appendTo('#email_form_print_options');
 
 111     var to_focus = $('#email_form_to').val() === '' ? 'to' : 'subject';
 
 112     $('#email_form_' + to_focus).focus();
 
 115   ns.finish_send_email_dialog = function() {
 
 116     kivi.SalesPurchase.show_all_print_options_elements();
 
 118     $('#email_form_print_options table').first().remove().prependTo('#print_options_form');
 
 122   ns.show_email_dialog = function(html) {
 
 123     var id            = 'send_email_dialog';
 
 124     var dialog_params = {
 
 128       title:  kivi.t8('Send email'),
 
 130       beforeClose: kivi.Order.finish_send_email_dialog,
 
 131       close: function(event, ui) {
 
 132         email_dialog.remove();
 
 136     $('#' + id).remove();
 
 138     email_dialog = $('<div style="display:none" id="' + id + '"></div>').appendTo('body');
 
 139     email_dialog.html(html);
 
 140     email_dialog.dialog(dialog_params);
 
 142     kivi.Order.setup_send_email_dialog();
 
 144     $('.cancel').click(ns.close_email_dialog);
 
 149   ns.send_email = function() {
 
 150     var data = $('#order_form').serializeArray();
 
 151     data = data.concat($('[name^="email_form."]').serializeArray());
 
 152     data = data.concat($('[name^="print_options."]').serializeArray());
 
 153     data.push({ name: 'order.language_id', value: $('#language_id').val() }); // language from print options
 
 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_dependent_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.redisplay_cvpartnumbers = function(data) {
 
 334     $('.row_entry').each(function(idx, elt) {
 
 335       $(elt).find('[name="cvpartnumber"]').html(data[idx][0]);
 
 339   ns.renumber_positions = function() {
 
 340     $('.row_entry [name="position"]').each(function(idx, elt) {
 
 343     $('.row_entry').each(function(idx, elt) {
 
 344       $(elt).data("position", idx+1);
 
 348   ns.reorder_items = function(order_by) {
 
 349     var dir = $('#' + order_by + '_header_id a img').attr("data-sort-dir");
 
 350     $('#row_table_id thead a img').remove();
 
 355       src = "image/up.png";
 
 358       src = "image/down.png";
 
 361     $('#' + order_by + '_header_id a').append('<img border=0 data-sort-dir=' + dir + ' src=' + src + ' alt="' + kivi.t8('sort items') + '">');
 
 363     var data = $('#order_form').serializeArray();
 
 364     data.push({ name: 'action',   value: 'Order/reorder_items' },
 
 365               { name: 'order_by', value: order_by              },
 
 366               { name: 'sort_dir', value: dir                   });
 
 368     $.post("controller.pl", data, kivi.eval_json_result);
 
 371   ns.redisplay_items = function(data) {
 
 372     var old_rows = $('.row_entry').detach();
 
 374     $(data).each(function(idx, elt) {
 
 375       new_rows.push(old_rows[elt.old_pos - 1]);
 
 377     $(new_rows).appendTo($('#row_table_id'));
 
 378     ns.renumber_positions();
 
 381   ns.get_insert_before_item_id = function(wanted_pos) {
 
 382     if (wanted_pos === '') return;
 
 384     var insert_before_item_id;
 
 385     // selection by data does not seem to work if data is changed at runtime
 
 386     // var elt = $('.row_entry [data-position="' + wanted_pos + '"]');
 
 387     $('.row_entry').each(function(idx, elt) {
 
 388       if ($(elt).data("position") == wanted_pos) {
 
 389         insert_before_item_id = $(elt).find('[name="orderitem_ids[+]"]').val();
 
 394     return insert_before_item_id;
 
 397   ns.add_item = function() {
 
 398     if ($('#add_item_parts_id').val() === '') return;
 
 399     if (!ns.check_cv()) return;
 
 401     $('#row_table_id thead a img').remove();
 
 403     var insert_before_item_id = ns.get_insert_before_item_id($('#add_item_position').val());
 
 405     var data = $('#order_form').serializeArray();
 
 406     data.push({ name: 'action', value: 'Order/add_item' },
 
 407               { name: 'insert_before_item_id', value: insert_before_item_id });
 
 409     $.post("controller.pl", data, kivi.eval_json_result);
 
 412   ns.setup_multi_items_dialog = function() {
 
 413     $('#multi_items_filter_table input, #multi_items_filter_table select').keydown(function(event) {
 
 414       if (event.keyCode == 13) {
 
 415         event.preventDefault();
 
 416         ns.multi_items_dialog_update_result();
 
 421     $('#multi_items_filter_all_substr_multi_ilike').focus();
 
 424   ns.show_multi_items_dialog = function() {
 
 425     if (!ns.check_cv()) return;
 
 427     $('#row_table_id thead a img').remove();
 
 430       url:    'controller.pl?action=Order/show_multi_items_dialog',
 
 431       data:   { type: $('#type').val() },
 
 432       id:     'jq_multi_items_dialog',
 
 433       load:   kivi.Order.setup_multi_items_dialog,
 
 435         title:  kivi.t8('Add multiple items'),
 
 443   ns.close_multi_items_dialog = function() {
 
 444     $('#jq_multi_items_dialog').dialog('close');
 
 447   ns.multi_items_dialog_update_result = function() {
 
 448     var data = $('#multi_items_form').serializeArray();
 
 449     data.push({ name: 'type', value: $('#type').val() });
 
 451       url:     'controller.pl?action=Order/multi_items_update_result',
 
 454       success: function(data) {
 
 455         $('#multi_items_result').html(data);
 
 456         ns.multi_items_dialog_enable_continue();
 
 457         ns.multi_items_result_setup_events();
 
 462   ns.multi_items_dialog_disable_continue = function() {
 
 463     // disable keydown-event and continue button to prevent
 
 464     // impatient users to add parts multiple times
 
 465     $('#multi_items_result input, #multi_items_position').off("keydown");
 
 466     $('#multi_items_dialog_continue_button').prop('disabled', true);
 
 469   ns.multi_items_dialog_enable_continue = function()  {
 
 470     $('#multi_items_result input, #multi_items_position').keydown(function(event) {
 
 471       if(event.keyCode == 13) {
 
 472         event.preventDefault();
 
 473         ns.add_multi_items();
 
 477     $('#multi_items_dialog_continue_button').prop('disabled', false);
 
 480   ns.multi_items_result_setup_events = function() {
 
 481     $('#multi_items_all_qty').change(ns.reformat_number);
 
 482     $('#multi_items_all_qty').change(function(event) {
 
 483       $('.multi_items_qty').val($(event.target).val());
 
 485     $('.multi_items_qty').change(ns.reformat_number);
 
 488   ns.add_multi_items = function() {
 
 490     var n_rows = $('.multi_items_qty').length;
 
 491     if (n_rows == 0) return;
 
 494     n_rows = $('.multi_items_qty').filter(function() {
 
 495       return $(this).val().length > 0;
 
 497     if (n_rows == 0) return;
 
 499     ns.multi_items_dialog_disable_continue();
 
 501     var insert_before_item_id = ns.get_insert_before_item_id($('#multi_items_position').val());
 
 503     var data = $('#order_form').serializeArray();
 
 504     data = data.concat($('#multi_items_form').serializeArray());
 
 505     data.push({ name: 'action', value: 'Order/add_multi_items' },
 
 506               { name: 'insert_before_item_id', value: insert_before_item_id });
 
 507     $.post("controller.pl", data, kivi.eval_json_result);
 
 510   ns.set_input_to_one = function(clicked) {
 
 511     if ($(clicked).val() == '') {
 
 512       $(clicked).val(kivi.format_amount(1.00, -2));
 
 517   ns.delete_order_item_row = function(clicked) {
 
 518     var row = $(clicked).parents("tbody").first();
 
 521     ns.renumber_positions();
 
 522     ns.recalc_amounts_and_taxes();
 
 525   ns.row_table_scroll_down = function() {
 
 526     $('#row_table_scroll_id').scrollTop($('#row_table_scroll_id')[0].scrollHeight);
 
 529   ns.show_longdescription_dialog = function(clicked) {
 
 530     var row                 = $(clicked).parents("tbody").first();
 
 531     var position            = $(row).find('[name="position"]').html();
 
 532     var partnumber          = $(row).find('[name="partnumber"]').html();
 
 533     var description_elt     = $(row).find('[name="order.orderitems[].description"]');
 
 534     var description         = description_elt.val();
 
 535     var longdescription_elt = $(row).find('[name="order.orderitems[].longdescription"]');
 
 538     if (!longdescription_elt.length) {
 
 540         { name: 'action',   value: 'Order/get_item_longdescription'                          },
 
 541         { name: 'type',     value: $('#type').val()                                          },
 
 542         { name: 'item_id',  value: $(row).find('[name="order.orderitems[+].id"]').val()      },
 
 543         { name: 'parts_id', value: $(row).find('[name="order.orderitems[].parts_id"]').val() }
 
 547         url:      'controller.pl',
 
 552         success:  function(val) {
 
 553           longdescription = val;
 
 557       longdescription = longdescription_elt.val();
 
 561       runningnumber:           position,
 
 562       partnumber:              partnumber,
 
 563       description:             description,
 
 564       default_longdescription: longdescription,
 
 565       set_function:            function(val) {
 
 566         longdescription_elt.remove();
 
 567         $('<input type="hidden" name="order.orderitems[].longdescription">').insertAfter(description_elt).val(val);
 
 571     kivi.SalesPurchase.edit_longdescription_with_params(params);
 
 574   ns.price_chooser_item_row = function(clicked) {
 
 575     if (!ns.check_cv()) return;
 
 576     var row         = $(clicked).parents("tbody").first();
 
 577     var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
 
 579     var data = $('#order_form').serializeArray();
 
 580     data.push({ name: 'action',  value: 'Order/price_popup' },
 
 581               { name: 'item_id', value: item_id_dom.val()   });
 
 583     $.post("controller.pl", data, kivi.eval_json_result);
 
 586   ns.update_price_source = function(item_id, source, descr, price_str, price_editable) {
 
 587     var row        = $('#item_' + item_id).parents("tbody").first();
 
 588     var source_elt = $(row).find('[name="order.orderitems[].active_price_source"]');
 
 589     var button_elt = $(row).find('[name="price_chooser_button"]');
 
 591     button_elt.val(button_elt.val().replace(/.*\|/, descr + " |"));
 
 592     source_elt.val(source);
 
 594     var editable_div_elt     = $(row).find('[name="editable_price"]');
 
 595     var not_editable_div_elt = $(row).find('[name="not_editable_price"]');
 
 596     if (price_editable == 1 && source === '') {
 
 598       $(editable_div_elt).show();
 
 599       $(not_editable_div_elt).hide();
 
 600       $(editable_div_elt).find(':input').prop("disabled", false);
 
 601       $(not_editable_div_elt).find(':input').prop("disabled", true);
 
 604       $(editable_div_elt).hide();
 
 605       $(not_editable_div_elt).show();
 
 606       $(editable_div_elt).find(':input').prop("disabled", true);
 
 607       $(not_editable_div_elt).find(':input').prop("disabled", false);
 
 611       var price_elt = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
 
 612       var html_elt  = $(row).find('[name="sellprice_text"]');
 
 613       price_elt.val(price_str);
 
 614       html_elt.html(price_str);
 
 615       ns.recalc_amounts_and_taxes();
 
 618     kivi.io.close_dialog();
 
 621   ns.update_discount_source = function(item_id, source, descr, discount_str, price_editable) {
 
 622     var row        = $('#item_' + item_id).parents("tbody").first();
 
 623     var source_elt = $(row).find('[name="order.orderitems[].active_discount_source"]');
 
 624     var button_elt = $(row).find('[name="price_chooser_button"]');
 
 626     button_elt.val(button_elt.val().replace(/\|.*/, "| " + descr));
 
 627     source_elt.val(source);
 
 629     var editable_div_elt     = $(row).find('[name="editable_discount"]');
 
 630     var not_editable_div_elt = $(row).find('[name="not_editable_discount"]');
 
 631     if (price_editable == 1 && source === '') {
 
 633       $(editable_div_elt).show();
 
 634       $(not_editable_div_elt).hide();
 
 635       $(editable_div_elt).find(':input').prop("disabled", false);
 
 636       $(not_editable_div_elt).find(':input').prop("disabled", true);
 
 639       $(editable_div_elt).hide();
 
 640       $(not_editable_div_elt).show();
 
 641       $(editable_div_elt).find(':input').prop("disabled", true);
 
 642       $(not_editable_div_elt).find(':input').prop("disabled", false);
 
 646       var discount_elt = $(row).find('[name="order.orderitems[].discount_as_percent"]');
 
 647       var html_elt     = $(row).find('[name="discount_text"]');
 
 648       discount_elt.val(discount_str);
 
 649       html_elt.html(discount_str);
 
 650       ns.recalc_amounts_and_taxes();
 
 653     kivi.io.close_dialog();
 
 656   ns.show_periodic_invoices_config_dialog = function() {
 
 657     if ($('#type').val() !== 'sales_order') return;
 
 660       url:    'controller.pl?action=Order/show_periodic_invoices_config_dialog',
 
 661       data:   { type:              $('#type').val(),
 
 663                 config:            $('#order_periodic_invoices_config').val(),
 
 664                 customer_id:       $('#order_customer_id').val(),
 
 665                 transdate_as_date: $('#order_transdate_as_date').val(),
 
 666                 language_id:       $('#language_id').val()
 
 668       id:     'jq_periodic_invoices_config_dialog',
 
 669       load:   kivi.reinit_widgets,
 
 671         title:  kivi.t8('Edit the configuration for periodic invoices'),
 
 679   ns.close_periodic_invoices_config_dialog = function() {
 
 680     $('#jq_periodic_invoices_config_dialog').dialog('close');
 
 683   ns.assign_periodic_invoices_config = function() {
 
 684     var data = $('[name="Form"]').serializeArray();
 
 685     data.push({ name: 'type',   value: $('#type').val() },
 
 686               { name: 'action', value: 'Order/assign_periodic_invoices_config' });
 
 687     $.post("controller.pl", data, kivi.eval_json_result);
 
 690   ns.check_save_active_periodic_invoices = function() {
 
 691     var type = $('#type').val();
 
 692     if (type !== 'sales_order') return true;
 
 696       url:      'controller.pl',
 
 697       data:     { action: 'Order/get_has_active_periodic_invoices',
 
 700                   config: $('#order_periodic_invoices_config').val(),
 
 705       success:  function(val) {
 
 711       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?'));
 
 717   ns.show_vc_details_dialog = function() {
 
 718     if (!ns.check_cv()) return;
 
 722     if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
 
 724       vc_id = $('#order_customer_id').val();
 
 725       title = kivi.t8('Customer details');
 
 728       vc_id = $('#order_vendor_id').val();
 
 729       title = kivi.t8('Vendor details');
 
 733       url:    'controller.pl',
 
 734       data:   { action: 'Order/show_customer_vendor_details_dialog',
 
 735                 type  : $('#type').val(),
 
 739       id:     'jq_customer_vendor_details_dialog',
 
 749   ns.update_row_from_master_data = function(clicked) {
 
 750     var row = $(clicked).parents("tbody").first();
 
 751     var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
 
 753     var data = $('#order_form').serializeArray();
 
 754     data.push({ name: 'action', value: 'Order/update_row_from_master_data' });
 
 755     data.push({ name: 'item_ids[]', value: item_id_dom.val() });
 
 757     $.post("controller.pl", data, kivi.eval_json_result);
 
 760   ns.update_all_rows_from_master_data = function() {
 
 761     var item_ids = $.map($('.row_entry'), function(elt) {
 
 762       var item_id = $(elt).find('[name="orderitem_ids[+]"]').val();
 
 763       return { name: 'item_ids[]', value: item_id };
 
 766     if (item_ids.length == 0) {
 
 770     var data = $('#order_form').serializeArray();
 
 771     data.push({ name: 'action', value: 'Order/update_row_from_master_data' });
 
 772     data = data.concat(item_ids);
 
 774     $.post("controller.pl", data, kivi.eval_json_result);
 
 777   ns.show_calculate_qty_dialog = function(clicked) {
 
 778     var row        = $(clicked).parents("tbody").first();
 
 779     var input_id   = $(row).find('[name="order.orderitems[].qty_as_number"]').attr('id');
 
 780     var formula_id = $(row).find('[name="formula[+]"]').attr('id');
 
 782     calculate_qty_selection_dialog("", input_id, "", formula_id);
 
 789   if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
 
 790     $('#order_customer_id').change(kivi.Order.reload_cv_dependent_selections);
 
 792     $('#order_vendor_id').change(kivi.Order.reload_cv_dependent_selections);
 
 795   if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
 
 796     $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_sellprice_as_number').val(kivi.format_amount(o.sellprice, -2)) });
 
 798     $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_sellprice_as_number').val(kivi.format_amount(o.lastcost, -2)) });
 
 800   $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_description').val(o.description) });
 
 801   $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_unit').val(o.unit) });
 
 803   $('.add_item_input').keydown(function(event) {
 
 804     if (event.keyCode == 13) {
 
 805       event.preventDefault();
 
 806       kivi.Order.add_item();
 
 811   kivi.Order.init_row_handlers();
 
 813   $('#row_table_id').on('sortstop', function(event, ui) {
 
 814     $('#row_table_id thead a img').remove();
 
 815     kivi.Order.renumber_positions();
 
 818   $('#expand_all').on('click', function(event) {
 
 819     event.preventDefault();
 
 820     if ($('#expand_all').data('expanded') == 1) {
 
 821       $('#expand_all').data('expanded', 0);
 
 822       $('#expand_all').attr('src', 'image/expand.svg');
 
 823       $('#expand_all').attr('alt', kivi.t8('Show all details'));
 
 824       $('#expand_all').attr('title', kivi.t8('Show all details'));
 
 825       $('.row_entry').each(function(idx, elt) {
 
 826         kivi.Order.hide_second_row(elt);
 
 829       $('#expand_all').data('expanded', 1);
 
 830       $('#expand_all').attr('src', "image/collapse.svg");
 
 831       $('#expand_all').attr('alt', kivi.t8('Hide all details'));
 
 832       $('#expand_all').attr('title', kivi.t8('Hide all details'));
 
 833       kivi.Order.load_all_second_rows();
 
 834       $('.row_entry').each(function(idx, elt) {
 
 835         kivi.Order.show_second_row(elt);