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_and_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     ns.set_discount_and_source_text(item_id, source, descr, discount_str, price_editable);
 
 635     if (discount_str) ns.recalc_amounts_and_taxes();
 
 636     kivi.io.close_dialog();
 
 639   ns.show_periodic_invoices_config_dialog = function() {
 
 640     if ($('#type').val() !== 'sales_order') return;
 
 643       url:    'controller.pl?action=Order/show_periodic_invoices_config_dialog',
 
 644       data:   { type:              $('#type').val(),
 
 646                 config:            $('#order_periodic_invoices_config').val(),
 
 647                 customer_id:       $('#order_customer_id').val(),
 
 648                 transdate_as_date: $('#order_transdate_as_date').val(),
 
 649                 language_id:       $('#language_id').val()
 
 651       id:     'jq_periodic_invoices_config_dialog',
 
 652       load:   kivi.reinit_widgets,
 
 654         title:  kivi.t8('Edit the configuration for periodic invoices'),
 
 662   ns.close_periodic_invoices_config_dialog = function() {
 
 663     $('#jq_periodic_invoices_config_dialog').dialog('close');
 
 666   ns.assign_periodic_invoices_config = function() {
 
 667     var data = $('[name="Form"]').serializeArray();
 
 668     data.push({ name: 'type',   value: $('#type').val() },
 
 669               { name: 'action', value: 'Order/assign_periodic_invoices_config' });
 
 670     $.post("controller.pl", data, kivi.eval_json_result);
 
 673   ns.check_save_active_periodic_invoices = function() {
 
 674     var type = $('#type').val();
 
 675     if (type !== 'sales_order') return true;
 
 679       url:      'controller.pl',
 
 680       data:     { action: 'Order/get_has_active_periodic_invoices',
 
 683                   config: $('#order_periodic_invoices_config').val(),
 
 688       success:  function(val) {
 
 694       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?'));
 
 700   ns.show_vc_details_dialog = function() {
 
 701     if (!ns.check_cv()) return;
 
 705     if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
 
 707       vc_id = $('#order_customer_id').val();
 
 708       title = kivi.t8('Customer details');
 
 711       vc_id = $('#order_vendor_id').val();
 
 712       title = kivi.t8('Vendor details');
 
 716       url:    'controller.pl',
 
 717       data:   { action: 'Order/show_customer_vendor_details_dialog',
 
 718                 type  : $('#type').val(),
 
 722       id:     'jq_customer_vendor_details_dialog',
 
 732   ns.update_row_from_master_data = function(clicked) {
 
 733     var row = $(clicked).parents("tbody").first();
 
 734     var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
 
 736     var data = $('#order_form').serializeArray();
 
 737     data.push({ name: 'action', value: 'Order/update_row_from_master_data' });
 
 738     data.push({ name: 'item_ids[]', value: item_id_dom.val() });
 
 740     $.post("controller.pl", data, kivi.eval_json_result);
 
 743   ns.update_all_rows_from_master_data = function() {
 
 744     var item_ids = $.map($('.row_entry'), function(elt) {
 
 745       var item_id = $(elt).find('[name="orderitem_ids[+]"]').val();
 
 746       return { name: 'item_ids[]', value: item_id };
 
 749     if (item_ids.length == 0) {
 
 753     var data = $('#order_form').serializeArray();
 
 754     data.push({ name: 'action', value: 'Order/update_row_from_master_data' });
 
 755     data = data.concat(item_ids);
 
 757     $.post("controller.pl", data, kivi.eval_json_result);
 
 760   ns.show_calculate_qty_dialog = function(clicked) {
 
 761     var row        = $(clicked).parents("tbody").first();
 
 762     var input_id   = $(row).find('[name="order.orderitems[].qty_as_number"]').attr('id');
 
 763     var formula_id = $(row).find('[name="formula[+]"]').attr('id');
 
 765     calculate_qty_selection_dialog("", input_id, "", formula_id);
 
 769   ns.edit_custom_shipto = function() {
 
 770     if (!ns.check_cv()) return;
 
 772     kivi.SalesPurchase.edit_custom_shipto();
 
 775   ns.purchase_order_check_for_direct_delivery = function() {
 
 776     if ($('#type').val() != 'sales_order') {
 
 777       kivi.submit_form_with_action($('#order_form'), 'Order/purchase_order');
 
 782     if ($('#order_shipto_id').val() !== '') {
 
 784       shipto = $('#order_shipto_id option:selected').text();
 
 786       $('#shipto_inputs [id^="shipto"]').each(function(idx, elt) {
 
 787         if (!empty)                                     return true;
 
 788         if (/^shipto_to_copy/.test($(elt).prop('id')))  return true;
 
 789         if (/^shiptocp_gender/.test($(elt).prop('id'))) return true;
 
 790         if (/^shiptocvar_/.test($(elt).prop('id')))     return true;
 
 791         if ($(elt).val() !== '') {
 
 796       var shipto_elements = [];
 
 797       $([$('#shiptoname').val(), $('#shiptostreet').val(), $('#shiptozipcode').val(), $('#shiptocity').val()]).each(function(idx, elt) {
 
 798         if (elt !== '') shipto_elements.push(elt);
 
 800       shipto = shipto_elements.join('; ');
 
 805       ns.direct_delivery_dialog(shipto);
 
 807       kivi.submit_form_with_action($('#order_form'), 'Order/purchase_order');
 
 811   ns.direct_delivery_callback = function(accepted) {
 
 812     $('#direct-delivery-dialog').dialog('close');
 
 815       $('<input type="hidden" name="use_shipto">').appendTo('#order_form').val('1');
 
 818     kivi.submit_form_with_action($('#order_form'), 'Order/purchase_order');
 
 821   ns.direct_delivery_dialog = function(shipto) {
 
 822     $('#direct-delivery-dialog').remove();
 
 824     var text1 = kivi.t8('You have entered or selected the following shipping address for this customer:');
 
 825     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?');
 
 826     var html  = '<div id="direct-delivery-dialog"><p>' + text1 + '</p><p>' + shipto + '</p><p>' + text2 + '</p>';
 
 827     html      = html + '<hr><p>';
 
 828     html      = html + '<input type="button" value="' + kivi.t8('Yes') + '" size="30" onclick="kivi.Order.direct_delivery_callback(true)">';
 
 829     html      = html + ' ';
 
 830     html      = html + '<input type="button" value="' + kivi.t8('No')  + '" size="30" onclick="kivi.Order.direct_delivery_callback(false)">';
 
 831     html      = html + '</p></div>';
 
 832     $(html).hide().appendTo('#order_form');
 
 834     kivi.popup_dialog({id: 'direct-delivery-dialog',
 
 835                        dialog: {title:  kivi.t8('Carry over shipping address'),
 
 840   ns.follow_up_window = function() {
 
 841     var id   = $('#id').val();
 
 842     var type = $('#type').val();
 
 844     var number_info = '';
 
 845     if ($('#type').val() == 'sales_order' || $('#type').val() == 'purchase_order') {
 
 846       number_info = $('#order_ordnumber').val();
 
 847     } else if ($('#type').val() == 'sales_quotation' || $('#type').val() == 'request_quotation') {
 
 848       number_info = $('#order_quonumber').val();
 
 852     if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation') {
 
 853       name_info = $('#order_customer_id_name').val();
 
 854     } else if ($('#type').val() == 'purchase_order' || $('#type').val() == 'request_quotation') {
 
 855       name_info = $('#order_vendor_id_name').val();
 
 859     if (number_info !== '') { info += ' (' + number_info + ')' }
 
 860     if (name_info   !== '') { info += ' (' + name_info + ')' }
 
 862     if (!$('#follow_up_rowcount').length) {
 
 863       $('<input type="hidden" name="follow_up_rowcount"        id="follow_up_rowcount">').appendTo('#order_form');
 
 864       $('<input type="hidden" name="follow_up_trans_id_1"      id="follow_up_trans_id_1">').appendTo('#order_form');
 
 865       $('<input type="hidden" name="follow_up_trans_type_1"    id="follow_up_trans_type_1">').appendTo('#order_form');
 
 866       $('<input type="hidden" name="follow_up_trans_info_1"    id="follow_up_trans_info_1">').appendTo('#order_form');
 
 867       $('<input type="hidden" name="follow_up_trans_subject_1" id="follow_up_trans_subject_1">').appendTo('#order_form');
 
 869     $('#follow_up_rowcount').val(1);
 
 870     $('#follow_up_trans_id_1').val(id);
 
 871     $('#follow_up_trans_type_1').val(type);
 
 872     $('#follow_up_trans_info_1').val(info);
 
 873     $('#follow_up_trans_subject_1').val($('#order_transaction_description').val());
 
 878   ns.create_part = function() {
 
 879     var data = $('#order_form').serializeArray();
 
 880     data.push({ name: 'action', value: 'Order/create_part' });
 
 882     $.post("controller.pl", data, kivi.eval_json_result);
 
 885   ns.check_transport_cost_article_presence = function() {
 
 886     var $form          = $('#order_form');
 
 887     var wanted_part_id = $form.data('transport-cost-reminder-article-id');
 
 889     if (!wanted_part_id) return true
 
 891     var id_arr = $('[name="order.orderitems[].parts_id"]').map(function() { return this.value; }).get();
 
 892     id_arr = $.grep(id_arr, function(elt) {
 
 893       return ((elt*1) === wanted_part_id);
 
 896     if (id_arr.length) return true;
 
 898     var description = $form.data('transport-cost-reminder-article-description');
 
 899     return confirm(kivi.t8("The transport cost article '#1' is missing. Do you want to continue anyway?", [ description ]));
 
 902   ns.check_cusordnumber_presence = function() {
 
 903     if ($('#order_cusordnumber').val() === '') {
 
 904       return confirm(kivi.t8('The customer order number is missing. Do you want to continue anyway?'));
 
 912   if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
 
 913     $('#order_customer_id').change(kivi.Order.reload_cv_dependent_selections);
 
 915     $('#order_vendor_id').change(kivi.Order.reload_cv_dependent_selections);
 
 918   $('#order_currency_id').change(kivi.Order.update_exchangerate);
 
 919   $('#order_transdate_as_date').change(kivi.Order.update_exchangerate);
 
 920   $('#order_exchangerate_as_null_number').change(kivi.Order.exchangerate_changed);
 
 922   $('#add_item_parts_id').on('set_item:PartPicker', function() {
 
 923     kivi.Order.update_item_input_row();
 
 926   $('.add_item_input').keydown(function(event) {
 
 927     if (event.keyCode == 13) {
 
 928       event.preventDefault();
 
 929       kivi.Order.add_item();
 
 934   kivi.Order.init_row_handlers();
 
 936   $('#row_table_id').on('sortstop', function(event, ui) {
 
 937     $('#row_table_id thead a img').remove();
 
 938     kivi.Order.renumber_positions();
 
 941   $('#expand_all').on('click', function(event) {
 
 942     event.preventDefault();
 
 943     if ($('#expand_all').data('expanded') == 1) {
 
 944       $('#expand_all').data('expanded', 0);
 
 945       $('#expand_all').attr('src', 'image/expand.svg');
 
 946       $('#expand_all').attr('alt', kivi.t8('Show all details'));
 
 947       $('#expand_all').attr('title', kivi.t8('Show all details'));
 
 948       $('.row_entry').each(function(idx, elt) {
 
 949         kivi.Order.hide_second_row(elt);
 
 952       $('#expand_all').data('expanded', 1);
 
 953       $('#expand_all').attr('src', "image/collapse.svg");
 
 954       $('#expand_all').attr('alt', kivi.t8('Hide all details'));
 
 955       $('#expand_all').attr('title', kivi.t8('Hide all details'));
 
 956       kivi.Order.load_all_second_rows();
 
 957       $('.row_entry').each(function(idx, elt) {
 
 958         kivi.Order.show_second_row(elt);
 
 964   $('.reformat_number_as_null_number').change(kivi.Order.reformat_number_as_null_number);