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 continue?");
 
  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, back_to_caller) {
 
  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     if (back_to_caller) data.push({ name: 'back_to_caller', value: '1' });
 
  58     $.post("controller.pl", data, kivi.eval_json_result);
 
  61   ns.delete_order = function() {
 
  62     var data = $('#order_form').serializeArray();
 
  63     data.push({ name: 'action', value: 'Order/delete' });
 
  65     $.post("controller.pl", data, kivi.eval_json_result);
 
  68   ns.show_print_options = function(warn_on_duplicates, warn_on_reqdate) {
 
  69     if (!ns.check_cv()) return;
 
  70     if (warn_on_duplicates && !ns.check_duplicate_parts(kivi.t8("Do you really want to print?"))) return;
 
  71     if (warn_on_reqdate    && !ns.check_valid_reqdate())   return;
 
  76         title: kivi.t8('Print options'),
 
  83   ns.print = function() {
 
  84     $('#print_options').dialog('close');
 
  86     var data = $('#order_form').serializeArray();
 
  87     data = data.concat($('#print_options_form').serializeArray());
 
  88     data.push({ name: 'action', value: 'Order/print' });
 
  90     $.post("controller.pl", data, kivi.eval_json_result);
 
  95   ns.setup_send_email_dialog = function() {
 
  96     kivi.SalesPurchase.show_all_print_options_elements();
 
  97     kivi.SalesPurchase.show_print_options_elements([ 'sendmode', 'media', 'copies', 'remove_draft' ], false);
 
  99     $('#print_options_form table').first().remove().appendTo('#email_form_print_options');
 
 101     $('select#format').change(kivi.Order.adjust_email_attachment_name_for_template_format);
 
 102     kivi.Order.adjust_email_attachment_name_for_template_format();
 
 104     var to_focus = $('#email_form_to').val() === '' ? 'to' : 'subject';
 
 105     $('#email_form_' + to_focus).focus();
 
 108   ns.finish_send_email_dialog = function() {
 
 109     kivi.SalesPurchase.show_all_print_options_elements();
 
 111     $('#email_form_print_options table').first().remove().prependTo('#print_options_form');
 
 115   ns.show_email_dialog = function(html) {
 
 116     var id            = 'send_email_dialog';
 
 117     var dialog_params = {
 
 121       title:  kivi.t8('Send email'),
 
 123       beforeClose: kivi.Order.finish_send_email_dialog,
 
 124       close: function(event, ui) {
 
 125         email_dialog.remove();
 
 129     $('#' + id).remove();
 
 131     email_dialog = $('<div style="display:none" id="' + id + '"></div>').appendTo('body');
 
 132     email_dialog.html(html);
 
 133     email_dialog.dialog(dialog_params);
 
 135     kivi.Order.setup_send_email_dialog();
 
 137     $('.cancel').click(ns.close_email_dialog);
 
 142   ns.send_email = function() {
 
 143     // push button only once -> slow response from mail server
 
 144     ns.email_dialog_disable_send();
 
 146     var data = $('#order_form').serializeArray();
 
 147     data = data.concat($('[name^="email_form."]').serializeArray());
 
 148     data = data.concat($('[name^="print_options."]').serializeArray());
 
 149     data.push({ name: 'action', value: 'Order/send_email' });
 
 150     $.post("controller.pl", data, kivi.eval_json_result);
 
 153   ns.email_dialog_disable_send = function() {
 
 154     // disable mail send event to prevent
 
 155     // impatient users to send multiple times
 
 156     $('#send_email').prop('disabled', true);
 
 159   ns.close_email_dialog = function() {
 
 160     email_dialog.dialog("close");
 
 163   ns.adjust_email_attachment_name_for_template_format = function() {
 
 164     var $filename_elt = $('#email_form_attachment_filename');
 
 165     var $format_elt   = $('select#format');
 
 167     if (!$filename_elt || !$format_elt)
 
 170     var format   = $format_elt.val().toLowerCase();
 
 171     var new_ext  = format == 'html' ? 'html' : format == 'opendocument' ? 'odt' : 'pdf';
 
 172     var filename = $filename_elt.val();
 
 174     $filename_elt.val(filename.replace(/[^.]+$/, new_ext));
 
 177   ns.set_number_in_title = function(elt) {
 
 178     $('#nr_in_title').html($(elt).val());
 
 181   ns.reload_cv_dependent_selections = function() {
 
 182     $('#order_shipto_id').val('');
 
 183     var data = $('#order_form').serializeArray();
 
 184     data.push({ name: 'action', value: 'Order/customer_vendor_changed' });
 
 186     $.post("controller.pl", data, kivi.eval_json_result);
 
 189   ns.reformat_number = function(event) {
 
 190     $(event.target).val(kivi.format_amount(kivi.parse_amount($(event.target).val()), -2));
 
 193   ns.reformat_number_as_null_number = function(event) {
 
 194     if ($(event.target).val() === '') {
 
 197     ns.reformat_number(event);
 
 200   ns.update_exchangerate = function(event) {
 
 201     if (!ns.check_cv()) {
 
 202       $('#order_currency_id').val($('#old_currency_id').val());
 
 206     var rate_input = $('#order_exchangerate_as_null_number');
 
 207     // unset exchangerate if currency changed
 
 208     if ($('#order_currency_id').val() !== $('#old_currency_id').val()) {
 
 212     // only set exchangerate if unset
 
 213     if (rate_input.val() !== '') {
 
 217     var data = $('#order_form').serializeArray();
 
 218     data.push({ name: 'action', value: 'Order/update_exchangerate' });
 
 221       url: 'controller.pl',
 
 225       success: function(data){
 
 226         if (!data.is_standard) {
 
 227           $('#currency_name').text(data.currency_name);
 
 228           if (data.exchangerate) {
 
 229             rate_input.val(data.exchangerate);
 
 233           $('#exchangerate_settings').show();
 
 236           $('#exchangerate_settings').hide();
 
 238         if ($('#order_currency_id').val() != $('#old_currency_id').val() ||
 
 239             !data.is_standard && data.exchangerate != $('#old_exchangerate').val()) {
 
 240           kivi.display_flash('warning', kivi.t8('You have changed the currency or exchange rate. Please check prices.'));
 
 242         $('#old_currency_id').val($('#order_currency_id').val());
 
 243         $('#old_exchangerate').val(data.exchangerate);
 
 248   ns.exchangerate_changed = function(event) {
 
 249     if (kivi.parse_amount($('#order_exchangerate_as_null_number').val()) != kivi.parse_amount($('#old_exchangerate').val())) {
 
 250       kivi.display_flash('warning', kivi.t8('You have changed the currency or exchange rate. Please check prices.'));
 
 251       $('#old_exchangerate').val($('#order_exchangerate_as_null_number').val());
 
 255   ns.recalc_amounts_and_taxes = function() {
 
 256     if (!kivi.validate_form('#order_form')) return;
 
 258     var data = $('#order_form').serializeArray();
 
 259     data.push({ name: 'action', value: 'Order/recalc_amounts_and_taxes' });
 
 261     $.post("controller.pl", data, kivi.eval_json_result);
 
 264   ns.unit_change = function(event) {
 
 265     var row           = $(event.target).parents("tbody").first();
 
 266     var item_id_dom   = $(row).find('[name="orderitem_ids[+]"]');
 
 267     var sellprice_dom = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
 
 268     var select_elt    = $(row).find('[name="order.orderitems[].unit"]');
 
 270     var oldval = $(select_elt).data('oldval');
 
 271     $(select_elt).data('oldval', $(select_elt).val());
 
 273     var data = $('#order_form').serializeArray();
 
 274     data.push({ name: 'action',           value: 'Order/unit_changed'     },
 
 275               { name: 'item_id',          value: item_id_dom.val()        },
 
 276               { name: 'old_unit',         value: oldval                   },
 
 277               { name: 'sellprice_dom_id', value: sellprice_dom.attr('id') });
 
 279     $.post("controller.pl", data, kivi.eval_json_result);
 
 282   ns.update_sellprice = function(item_id, price_str) {
 
 283     var row       = $('#item_' + item_id).parents("tbody").first();
 
 284     var price_elt = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
 
 285     var html_elt  = $(row).find('[name="sellprice_text"]');
 
 286     price_elt.val(price_str);
 
 287     html_elt.html(price_str);
 
 290   ns.load_second_row = function(row) {
 
 291     var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
 
 292     var div_elt     = $(row).find('[name="second_row"]');
 
 294     if ($(div_elt).data('loaded') == 1) {
 
 297     var data = $('#order_form').serializeArray();
 
 298     data.push({ name: 'action',     value: 'Order/load_second_rows' },
 
 299               { name: 'item_ids[]', value: item_id_dom.val()        });
 
 301     $.post("controller.pl", data, kivi.eval_json_result);
 
 304   ns.load_all_second_rows = function() {
 
 305     var rows = $('.row_entry').filter(function(idx, elt) {
 
 306       return $(elt).find('[name="second_row"]').data('loaded') != 1;
 
 309     var item_ids = $.map(rows, function(elt) {
 
 310       var item_id = $(elt).find('[name="orderitem_ids[+]"]').val();
 
 311       return { name: 'item_ids[]', value: item_id };
 
 314     if (item_ids.length == 0) {
 
 318     var data = $('#order_form').serializeArray();
 
 319     data.push({ name: 'action', value: 'Order/load_second_rows' });
 
 320     data = data.concat(item_ids);
 
 322     $.post("controller.pl", data, kivi.eval_json_result);
 
 325   ns.hide_second_row = function(row) {
 
 326     $(row).children().not(':first').hide();
 
 327     $(row).data('expanded', 0);
 
 328     var elt = $(row).find('.expand');
 
 329     elt.attr('src', "image/expand.svg");
 
 330     elt.attr('alt', kivi.t8('Show details'));
 
 331     elt.attr('title', kivi.t8('Show details'));
 
 334   ns.show_second_row = function(row) {
 
 335     $(row).children().not(':first').show();
 
 336     $(row).data('expanded', 1);
 
 337     var elt = $(row).find('.expand');
 
 338     elt.attr('src', "image/collapse.svg");
 
 339     elt.attr('alt', kivi.t8('Hide details'));
 
 340     elt.attr('title', kivi.t8('Hide details'));
 
 343   ns.toggle_second_row = function(row) {
 
 344     if ($(row).data('expanded') == 1) {
 
 345       ns.hide_second_row(row);
 
 347       ns.show_second_row(row);
 
 351   ns.init_row_handlers = function() {
 
 352     kivi.run_once_for('.recalc', 'on_change_recalc', function(elt) {
 
 353       $(elt).change(ns.recalc_amounts_and_taxes);
 
 356     kivi.run_once_for('.reformat_number', 'on_change_reformat', function(elt) {
 
 357       $(elt).change(ns.reformat_number);
 
 360     kivi.run_once_for('.unitselect', 'on_change_unit_with_oldval', function(elt) {
 
 361       $(elt).data('oldval', $(elt).val());
 
 362       $(elt).change(ns.unit_change);
 
 365     kivi.run_once_for('.row_entry', 'on_kbd_click_show_hide', function(elt) {
 
 366       $(elt).keydown(function(event) {
 
 368         if (event.keyCode == 40 && event.shiftKey === true) {
 
 370           event.preventDefault();
 
 371           row = $(event.target).parents(".row_entry").first();
 
 372           ns.load_second_row(row);
 
 373           ns.show_second_row(row);
 
 376         if (event.keyCode == 38 && event.shiftKey === true) {
 
 378           event.preventDefault();
 
 379           row = $(event.target).parents(".row_entry").first();
 
 380           ns.hide_second_row(row);
 
 386     kivi.run_once_for('.expand', 'expand_second_row', function(elt) {
 
 387       $(elt).click(function(event) {
 
 388         event.preventDefault();
 
 389         var row = $(event.target).parents(".row_entry").first();
 
 390         ns.load_second_row(row);
 
 391         ns.toggle_second_row(row);
 
 398   ns.redisplay_line_values = function(is_sales, data) {
 
 399     $('.row_entry').each(function(idx, elt) {
 
 400       $(elt).find('[name="linetotal"]').html(data[idx][0]);
 
 401       if (is_sales && $(elt).find('[name="second_row"]').data('loaded') == 1) {
 
 402         var mt = data[idx][1];
 
 403         var mp = data[idx][2];
 
 405         if (mt[0] === '-') h += ' class="plus0"';
 
 406         h += '>' + mt + '  ' + mp + '%';
 
 408         $(elt).find('[name="linemargin"]').html(h);
 
 413   ns.redisplay_cvpartnumbers = function(data) {
 
 414     $('.row_entry').each(function(idx, elt) {
 
 415       $(elt).find('[name="cvpartnumber"]').html(data[idx][0]);
 
 419   ns.renumber_positions = function() {
 
 420     $('.row_entry [name="position"]').each(function(idx, elt) {
 
 423     $('.row_entry').each(function(idx, elt) {
 
 424       $(elt).data("position", idx+1);
 
 428   ns.reorder_items = function(order_by) {
 
 429     var dir = $('#' + order_by + '_header_id a img').attr("data-sort-dir");
 
 430     $('#row_table_id thead a img').remove();
 
 435       src = "image/up.png";
 
 438       src = "image/down.png";
 
 441     $('#' + order_by + '_header_id a').append('<img border=0 data-sort-dir=' + dir + ' src=' + src + ' alt="' + kivi.t8('sort items') + '">');
 
 443     var data = $('#order_form').serializeArray();
 
 444     data.push({ name: 'action',   value: 'Order/reorder_items' },
 
 445               { name: 'order_by', value: order_by              },
 
 446               { name: 'sort_dir', value: dir                   });
 
 448     $.post("controller.pl", data, kivi.eval_json_result);
 
 451   ns.redisplay_items = function(data) {
 
 452     var old_rows = $('.row_entry').detach();
 
 454     $(data).each(function(idx, elt) {
 
 455       new_rows.push(old_rows[elt.old_pos - 1]);
 
 457     $(new_rows).appendTo($('#row_table_id'));
 
 458     ns.renumber_positions();
 
 461   ns.get_insert_before_item_id = function(wanted_pos) {
 
 462     if (wanted_pos === '') return;
 
 464     var insert_before_item_id;
 
 465     // selection by data does not seem to work if data is changed at runtime
 
 466     // var elt = $('.row_entry [data-position="' + wanted_pos + '"]');
 
 467     $('.row_entry').each(function(idx, elt) {
 
 468       if ($(elt).data("position") == wanted_pos) {
 
 469         insert_before_item_id = $(elt).find('[name="orderitem_ids[+]"]').val();
 
 474     return insert_before_item_id;
 
 477   ns.update_item_input_row = function() {
 
 478     if (!ns.check_cv()) return;
 
 480     var data = $('#order_form').serializeArray();
 
 481     data.push({ name: 'action', value: 'Order/update_item_input_row' });
 
 483     $.post("controller.pl", data, kivi.eval_json_result);
 
 486   ns.add_item = function() {
 
 487     if ($('#add_item_parts_id').val() === '') return;
 
 488     if (!ns.check_cv()) return;
 
 490     $('#row_table_id thead a img').remove();
 
 492     var insert_before_item_id = ns.get_insert_before_item_id($('#add_item_position').val());
 
 494     var data = $('#order_form').serializeArray();
 
 495     data.push({ name: 'action', value: 'Order/add_item' },
 
 496               { name: 'insert_before_item_id', value: insert_before_item_id });
 
 498     $.post("controller.pl", data, kivi.eval_json_result);
 
 501   ns.open_multi_items_dialog = function() {
 
 502     if (!ns.check_cv()) return;
 
 504     var pp = $("#add_item_parts_id").data("part_picker");
 
 509   ns.add_multi_items = function(data) {
 
 510     var insert_before_item_id = ns.get_insert_before_item_id($('#multi_items_position').val());
 
 511     data = data.concat($('#order_form').serializeArray());
 
 512     data.push({ name: 'action', value: 'Order/add_multi_items' },
 
 513               { name: 'insert_before_item_id', value: insert_before_item_id });
 
 514     $.post("controller.pl", data, kivi.eval_json_result);
 
 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 longdescription_elt = $(row).find('[name="order.orderitems[].longdescription"]');
 
 537       runningnumber:           position,
 
 538       partnumber:              partnumber,
 
 539       description:             description_elt.val(),
 
 540       default_longdescription: longdescription_elt.val(),
 
 541       set_function:            function(val) {
 
 542         longdescription_elt.val(val);
 
 546     kivi.SalesPurchase.edit_longdescription_with_params(params);
 
 549   ns.price_chooser_item_row = function(clicked) {
 
 550     if (!ns.check_cv()) return;
 
 551     var row         = $(clicked).parents("tbody").first();
 
 552     var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
 
 554     var data = $('#order_form').serializeArray();
 
 555     data.push({ name: 'action',  value: 'Order/price_popup' },
 
 556               { name: 'item_id', value: item_id_dom.val()   });
 
 558     $.post("controller.pl", data, kivi.eval_json_result);
 
 561   ns.set_price_and_source_text = function(item_id, source, descr, price_str, price_editable) {
 
 562     var row        = $('#item_' + item_id).parents("tbody").first();
 
 563     var source_elt = $(row).find('[name="order.orderitems[].active_price_source"]');
 
 564     var button_elt = $(row).find('[name="price_chooser_button"]');
 
 566     button_elt.val(button_elt.val().replace(/.*\|/, descr + " |"));
 
 567     source_elt.val(source);
 
 569     var editable_div_elt     = $(row).find('[name="editable_price"]');
 
 570     var not_editable_div_elt = $(row).find('[name="not_editable_price"]');
 
 571     if (price_editable == 1 && source === '') {
 
 573       $(editable_div_elt).show();
 
 574       $(not_editable_div_elt).hide();
 
 575       $(editable_div_elt).find(':input').prop("disabled", false);
 
 576       $(not_editable_div_elt).find(':input').prop("disabled", true);
 
 579       $(editable_div_elt).hide();
 
 580       $(not_editable_div_elt).show();
 
 581       $(editable_div_elt).find(':input').prop("disabled", true);
 
 582       $(not_editable_div_elt).find(':input').prop("disabled", false);
 
 586       var price_elt = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
 
 587       var html_elt  = $(row).find('[name="sellprice_text"]');
 
 588       price_elt.val(price_str);
 
 589       html_elt.html(price_str);
 
 593   ns.update_price_source = function(item_id, source, descr, price_str, price_editable) {
 
 594     ns.set_price_source_text(item_id, source, descr, price_str, price_editable);
 
 596     if (price_str) ns.recalc_amounts_and_taxes();
 
 597     kivi.io.close_dialog();
 
 600   ns.set_discount_and_source_text = 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);
 
 632   ns.update_discount_source = function(item_id, source, descr, discount_str, price_editable) {
 
 633     if (discount_str) ns.recalc_amounts_and_taxes();
 
 634     kivi.io.close_dialog();
 
 637   ns.show_periodic_invoices_config_dialog = function() {
 
 638     if ($('#type').val() !== 'sales_order') return;
 
 641       url:    'controller.pl?action=Order/show_periodic_invoices_config_dialog',
 
 642       data:   { type:              $('#type').val(),
 
 644                 config:            $('#order_periodic_invoices_config').val(),
 
 645                 customer_id:       $('#order_customer_id').val(),
 
 646                 transdate_as_date: $('#order_transdate_as_date').val(),
 
 647                 language_id:       $('#language_id').val()
 
 649       id:     'jq_periodic_invoices_config_dialog',
 
 650       load:   kivi.reinit_widgets,
 
 652         title:  kivi.t8('Edit the configuration for periodic invoices'),
 
 660   ns.close_periodic_invoices_config_dialog = function() {
 
 661     $('#jq_periodic_invoices_config_dialog').dialog('close');
 
 664   ns.assign_periodic_invoices_config = function() {
 
 665     var data = $('[name="Form"]').serializeArray();
 
 666     data.push({ name: 'type',   value: $('#type').val() },
 
 667               { name: 'action', value: 'Order/assign_periodic_invoices_config' });
 
 668     $.post("controller.pl", data, kivi.eval_json_result);
 
 671   ns.check_save_active_periodic_invoices = function() {
 
 672     var type = $('#type').val();
 
 673     if (type !== 'sales_order') return true;
 
 677       url:      'controller.pl',
 
 678       data:     { action: 'Order/get_has_active_periodic_invoices',
 
 681                   config: $('#order_periodic_invoices_config').val(),
 
 686       success:  function(val) {
 
 692       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?'));
 
 698   ns.show_vc_details_dialog = function() {
 
 699     if (!ns.check_cv()) return;
 
 703     if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
 
 705       vc_id = $('#order_customer_id').val();
 
 706       title = kivi.t8('Customer details');
 
 709       vc_id = $('#order_vendor_id').val();
 
 710       title = kivi.t8('Vendor details');
 
 714       url:    'controller.pl',
 
 715       data:   { action: 'Order/show_customer_vendor_details_dialog',
 
 716                 type  : $('#type').val(),
 
 720       id:     'jq_customer_vendor_details_dialog',
 
 730   ns.update_row_from_master_data = function(clicked) {
 
 731     var row = $(clicked).parents("tbody").first();
 
 732     var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
 
 734     var data = $('#order_form').serializeArray();
 
 735     data.push({ name: 'action', value: 'Order/update_row_from_master_data' });
 
 736     data.push({ name: 'item_ids[]', value: item_id_dom.val() });
 
 738     $.post("controller.pl", data, kivi.eval_json_result);
 
 741   ns.update_all_rows_from_master_data = function() {
 
 742     var item_ids = $.map($('.row_entry'), function(elt) {
 
 743       var item_id = $(elt).find('[name="orderitem_ids[+]"]').val();
 
 744       return { name: 'item_ids[]', value: item_id };
 
 747     if (item_ids.length == 0) {
 
 751     var data = $('#order_form').serializeArray();
 
 752     data.push({ name: 'action', value: 'Order/update_row_from_master_data' });
 
 753     data = data.concat(item_ids);
 
 755     $.post("controller.pl", data, kivi.eval_json_result);
 
 758   ns.show_calculate_qty_dialog = function(clicked) {
 
 759     var row        = $(clicked).parents("tbody").first();
 
 760     var input_id   = $(row).find('[name="order.orderitems[].qty_as_number"]').attr('id');
 
 761     var formula_id = $(row).find('[name="formula[+]"]').attr('id');
 
 763     calculate_qty_selection_dialog("", input_id, "", formula_id);
 
 767   ns.edit_custom_shipto = function() {
 
 768     if (!ns.check_cv()) return;
 
 770     kivi.SalesPurchase.edit_custom_shipto();
 
 773   ns.purchase_order_check_for_direct_delivery = function() {
 
 774     if ($('#type').val() != 'sales_order') {
 
 775       kivi.submit_form_with_action($('#order_form'), 'Order/purchase_order');
 
 780     if ($('#order_shipto_id').val() !== '') {
 
 782       shipto = $('#order_shipto_id option:selected').text();
 
 784       $('#shipto_inputs [id^="shipto"]').each(function(idx, elt) {
 
 785         if (!empty)                                     return true;
 
 786         if (/^shipto_to_copy/.test($(elt).prop('id')))  return true;
 
 787         if (/^shiptocp_gender/.test($(elt).prop('id'))) return true;
 
 788         if (/^shiptocvar_/.test($(elt).prop('id')))     return true;
 
 789         if ($(elt).val() !== '') {
 
 794       var shipto_elements = [];
 
 795       $([$('#shiptoname').val(), $('#shiptostreet').val(), $('#shiptozipcode').val(), $('#shiptocity').val()]).each(function(idx, elt) {
 
 796         if (elt !== '') shipto_elements.push(elt);
 
 798       shipto = shipto_elements.join('; ');
 
 803       ns.direct_delivery_dialog(shipto);
 
 805       kivi.submit_form_with_action($('#order_form'), 'Order/purchase_order');
 
 809   ns.direct_delivery_callback = function(accepted) {
 
 810     $('#direct-delivery-dialog').dialog('close');
 
 813       $('<input type="hidden" name="use_shipto">').appendTo('#order_form').val('1');
 
 816     kivi.submit_form_with_action($('#order_form'), 'Order/purchase_order');
 
 819   ns.direct_delivery_dialog = function(shipto) {
 
 820     $('#direct-delivery-dialog').remove();
 
 822     var text1 = kivi.t8('You have entered or selected the following shipping address for this customer:');
 
 823     var text2 = kivi.t8('Do you want to carry this shipping address over to the new purchase order so that the vendor can deliver the goods directly to your customer?');
 
 824     var html  = '<div id="direct-delivery-dialog"><p>' + text1 + '</p><p>' + shipto + '</p><p>' + text2 + '</p>';
 
 825     html      = html + '<hr><p>';
 
 826     html      = html + '<input type="button" value="' + kivi.t8('Yes') + '" size="30" onclick="kivi.Order.direct_delivery_callback(true)">';
 
 827     html      = html + ' ';
 
 828     html      = html + '<input type="button" value="' + kivi.t8('No')  + '" size="30" onclick="kivi.Order.direct_delivery_callback(false)">';
 
 829     html      = html + '</p></div>';
 
 830     $(html).hide().appendTo('#order_form');
 
 832     kivi.popup_dialog({id: 'direct-delivery-dialog',
 
 833                        dialog: {title:  kivi.t8('Carry over shipping address'),
 
 838   ns.follow_up_window = function() {
 
 839     var id   = $('#id').val();
 
 840     var type = $('#type').val();
 
 842     var number_info = '';
 
 843     if ($('#type').val() == 'sales_order' || $('#type').val() == 'purchase_order') {
 
 844       number_info = $('#order_ordnumber').val();
 
 845     } else if ($('#type').val() == 'sales_quotation' || $('#type').val() == 'request_quotation') {
 
 846       number_info = $('#order_quonumber').val();
 
 850     if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation') {
 
 851       name_info = $('#order_customer_id_name').val();
 
 852     } else if ($('#type').val() == 'purchase_order' || $('#type').val() == 'request_quotation') {
 
 853       name_info = $('#order_vendor_id_name').val();
 
 857     if (number_info !== '') { info += ' (' + number_info + ')' }
 
 858     if (name_info   !== '') { info += ' (' + name_info + ')' }
 
 860     if (!$('#follow_up_rowcount').length) {
 
 861       $('<input type="hidden" name="follow_up_rowcount"        id="follow_up_rowcount">').appendTo('#order_form');
 
 862       $('<input type="hidden" name="follow_up_trans_id_1"      id="follow_up_trans_id_1">').appendTo('#order_form');
 
 863       $('<input type="hidden" name="follow_up_trans_type_1"    id="follow_up_trans_type_1">').appendTo('#order_form');
 
 864       $('<input type="hidden" name="follow_up_trans_info_1"    id="follow_up_trans_info_1">').appendTo('#order_form');
 
 865       $('<input type="hidden" name="follow_up_trans_subject_1" id="follow_up_trans_subject_1">').appendTo('#order_form');
 
 867     $('#follow_up_rowcount').val(1);
 
 868     $('#follow_up_trans_id_1').val(id);
 
 869     $('#follow_up_trans_type_1').val(type);
 
 870     $('#follow_up_trans_info_1').val(info);
 
 871     $('#follow_up_trans_subject_1').val($('#order_transaction_description').val());
 
 876   ns.create_part = function() {
 
 877     var data = $('#order_form').serializeArray();
 
 878     data.push({ name: 'action', value: 'Order/create_part' });
 
 880     $.post("controller.pl", data, kivi.eval_json_result);
 
 883   ns.check_transport_cost_article_presence = function() {
 
 884     var $form          = $('#order_form');
 
 885     var wanted_part_id = $form.data('transport-cost-reminder-article-id');
 
 887     if (!wanted_part_id) return true
 
 889     var id_arr = $('[name="order.orderitems[].parts_id"]').map(function() { return this.value; }).get();
 
 890     id_arr = $.grep(id_arr, function(elt) {
 
 891       return ((elt*1) === wanted_part_id);
 
 894     if (id_arr.length) return true;
 
 896     var description = $form.data('transport-cost-reminder-article-description');
 
 897     return confirm(kivi.t8("The transport cost article '#1' is missing. Do you want to continue anyway?", [ description ]));
 
 900   ns.check_cusordnumber_presence = function() {
 
 901     if ($('#order_cusordnumber').val() === '') {
 
 902       return confirm(kivi.t8('The customer order number is missing. Do you want to continue anyway?'));
 
 910   if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
 
 911     $('#order_customer_id').change(kivi.Order.reload_cv_dependent_selections);
 
 913     $('#order_vendor_id').change(kivi.Order.reload_cv_dependent_selections);
 
 916   $('#order_currency_id').change(kivi.Order.update_exchangerate);
 
 917   $('#order_transdate_as_date').change(kivi.Order.update_exchangerate);
 
 918   $('#order_exchangerate_as_null_number').change(kivi.Order.exchangerate_changed);
 
 920   $('#add_item_parts_id').on('set_item:PartPicker', function() {
 
 921     kivi.Order.update_item_input_row();
 
 924   $('.add_item_input').keydown(function(event) {
 
 925     if (event.keyCode == 13) {
 
 926       event.preventDefault();
 
 927       kivi.Order.add_item();
 
 932   kivi.Order.init_row_handlers();
 
 934   $('#row_table_id').on('sortstop', function(event, ui) {
 
 935     $('#row_table_id thead a img').remove();
 
 936     kivi.Order.renumber_positions();
 
 939   $('#expand_all').on('click', function(event) {
 
 940     event.preventDefault();
 
 941     if ($('#expand_all').data('expanded') == 1) {
 
 942       $('#expand_all').data('expanded', 0);
 
 943       $('#expand_all').attr('src', 'image/expand.svg');
 
 944       $('#expand_all').attr('alt', kivi.t8('Show all details'));
 
 945       $('#expand_all').attr('title', kivi.t8('Show all details'));
 
 946       $('.row_entry').each(function(idx, elt) {
 
 947         kivi.Order.hide_second_row(elt);
 
 950       $('#expand_all').data('expanded', 1);
 
 951       $('#expand_all').attr('src', "image/collapse.svg");
 
 952       $('#expand_all').attr('alt', kivi.t8('Hide all details'));
 
 953       $('#expand_all').attr('title', kivi.t8('Hide all details'));
 
 954       kivi.Order.load_all_second_rows();
 
 955       $('.row_entry').each(function(idx, elt) {
 
 956         kivi.Order.show_second_row(elt);
 
 962   $('.reformat_number_as_null_number').change(kivi.Order.reformat_number_as_null_number);