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) {
 
  49     if (!ns.check_cv()) return;
 
  50     if (warn_on_duplicates && !ns.check_duplicate_parts()) return;
 
  51     if (warn_on_reqdate    && !ns.check_valid_reqdate())   return;
 
  53     var data = $('#order_form').serializeArray();
 
  54     data.push({ name: 'action', value: 'Order/' + action });
 
  56     $.post("controller.pl", data, kivi.eval_json_result);
 
  59   ns.delete_order = function() {
 
  60     var data = $('#order_form').serializeArray();
 
  61     data.push({ name: 'action', value: 'Order/delete' });
 
  63     $.post("controller.pl", data, kivi.eval_json_result);
 
  66   ns.show_print_options = function(warn_on_duplicates, warn_on_reqdate) {
 
  67     if (!ns.check_cv()) return;
 
  68     if (warn_on_duplicates && !ns.check_duplicate_parts(kivi.t8("Do you really want to print?"))) return;
 
  69     if (warn_on_reqdate    && !ns.check_valid_reqdate())   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: 'action', value: 'Order/print' });
 
  88     $.post("controller.pl", data, kivi.eval_json_result);
 
  93   ns.setup_send_email_dialog = function() {
 
  94     kivi.SalesPurchase.show_all_print_options_elements();
 
  95     kivi.SalesPurchase.show_print_options_elements([ 'sendmode', 'media', 'copies', 'remove_draft' ], false);
 
  97     $('#print_options_form table').first().remove().appendTo('#email_form_print_options');
 
  99     var to_focus = $('#email_form_to').val() === '' ? 'to' : 'subject';
 
 100     $('#email_form_' + to_focus).focus();
 
 103   ns.finish_send_email_dialog = function() {
 
 104     kivi.SalesPurchase.show_all_print_options_elements();
 
 106     $('#email_form_print_options table').first().remove().prependTo('#print_options_form');
 
 110   ns.show_email_dialog = function(html) {
 
 111     var id            = 'send_email_dialog';
 
 112     var dialog_params = {
 
 116       title:  kivi.t8('Send email'),
 
 118       beforeClose: kivi.Order.finish_send_email_dialog,
 
 119       close: function(event, ui) {
 
 120         email_dialog.remove();
 
 124     $('#' + id).remove();
 
 126     email_dialog = $('<div style="display:none" id="' + id + '"></div>').appendTo('body');
 
 127     email_dialog.html(html);
 
 128     email_dialog.dialog(dialog_params);
 
 130     kivi.Order.setup_send_email_dialog();
 
 132     $('.cancel').click(ns.close_email_dialog);
 
 137   ns.send_email = function() {
 
 138     // push button only once -> slow response from mail server
 
 139     ns.email_dialog_disable_send();
 
 141     var data = $('#order_form').serializeArray();
 
 142     data = data.concat($('[name^="email_form."]').serializeArray());
 
 143     data = data.concat($('[name^="print_options."]').serializeArray());
 
 144     data.push({ name: 'action', value: 'Order/send_email' });
 
 145     $.post("controller.pl", data, kivi.eval_json_result);
 
 148   ns.email_dialog_disable_send = function() {
 
 149     // disable mail send event to prevent
 
 150     // impatient users to send multiple times
 
 151     $('#send_email').prop('disabled', true);
 
 154   ns.close_email_dialog = function() {
 
 155     email_dialog.dialog("close");
 
 158   ns.set_number_in_title = function(elt) {
 
 159     $('#nr_in_title').html($(elt).val());
 
 162   ns.reload_cv_dependent_selections = function() {
 
 163     $('#order_shipto_id').val('');
 
 164     var data = $('#order_form').serializeArray();
 
 165     data.push({ name: 'action', value: 'Order/customer_vendor_changed' });
 
 167     $.post("controller.pl", data, kivi.eval_json_result);
 
 170   ns.reformat_number = function(event) {
 
 171     $(event.target).val(kivi.format_amount(kivi.parse_amount($(event.target).val()), -2));
 
 174   ns.reformat_number_as_null_number = function(event) {
 
 175     if ($(event.target).val() === '') {
 
 178     ns.reformat_number(event);
 
 181   ns.update_exchangerate = function(event) {
 
 182     if (!ns.check_cv()) {
 
 183       $('#order_currency_id').val($('#old_currency_id').val());
 
 187     var rate_input = $('#order_exchangerate_as_null_number');
 
 188     // unset exchangerate if currency changed
 
 189     if ($('#order_currency_id').val() !== $('#old_currency_id').val()) {
 
 193     // only set exchangerate if unset
 
 194     if (rate_input.val() !== '') {
 
 198     var data = $('#order_form').serializeArray();
 
 199     data.push({ name: 'action', value: 'Order/update_exchangerate' });
 
 202       url: 'controller.pl',
 
 206       success: function(data){
 
 207         if (!data.is_standard) {
 
 208           $('#currency_name').text(data.currency_name);
 
 209           if (data.exchangerate) {
 
 210             rate_input.val(data.exchangerate);
 
 214           $('#exchangerate_settings').show();
 
 217           $('#exchangerate_settings').hide();
 
 219         if ($('#order_currency_id').val() != $('#old_currency_id').val() ||
 
 220             !data.is_standard && data.exchangerate != $('#old_exchangerate').val()) {
 
 221           kivi.display_flash('warning', kivi.t8('You have changed the currency or exchange rate. Please check prices.'));
 
 223         $('#old_currency_id').val($('#order_currency_id').val());
 
 224         $('#old_exchangerate').val(data.exchangerate);
 
 229   ns.exchangerate_changed = function(event) {
 
 230     if (kivi.parse_amount($('#order_exchangerate_as_null_number').val()) != kivi.parse_amount($('#old_exchangerate').val())) {
 
 231       kivi.display_flash('warning', kivi.t8('You have changed the currency or exchange rate. Please check prices.'));
 
 232       $('#old_exchangerate').val($('#order_exchangerate_as_null_number').val());
 
 236   ns.recalc_amounts_and_taxes = function() {
 
 237     var data = $('#order_form').serializeArray();
 
 238     data.push({ name: 'action', value: 'Order/recalc_amounts_and_taxes' });
 
 240     $.post("controller.pl", data, kivi.eval_json_result);
 
 243   ns.unit_change = function(event) {
 
 244     var row           = $(event.target).parents("tbody").first();
 
 245     var item_id_dom   = $(row).find('[name="orderitem_ids[+]"]');
 
 246     var sellprice_dom = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
 
 247     var select_elt    = $(row).find('[name="order.orderitems[].unit"]');
 
 249     var oldval = $(select_elt).data('oldval');
 
 250     $(select_elt).data('oldval', $(select_elt).val());
 
 252     var data = $('#order_form').serializeArray();
 
 253     data.push({ name: 'action',           value: 'Order/unit_changed'     },
 
 254               { name: 'item_id',          value: item_id_dom.val()        },
 
 255               { name: 'old_unit',         value: oldval                   },
 
 256               { name: 'sellprice_dom_id', value: sellprice_dom.attr('id') });
 
 258     $.post("controller.pl", data, kivi.eval_json_result);
 
 261   ns.update_sellprice = function(item_id, price_str) {
 
 262     var row       = $('#item_' + item_id).parents("tbody").first();
 
 263     var price_elt = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
 
 264     var html_elt  = $(row).find('[name="sellprice_text"]');
 
 265     price_elt.val(price_str);
 
 266     html_elt.html(price_str);
 
 269   ns.load_second_row = function(row) {
 
 270     var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
 
 271     var div_elt     = $(row).find('[name="second_row"]');
 
 273     if ($(div_elt).data('loaded') == 1) {
 
 276     var data = $('#order_form').serializeArray();
 
 277     data.push({ name: 'action',     value: 'Order/load_second_rows' },
 
 278               { name: 'item_ids[]', value: item_id_dom.val()        });
 
 280     $.post("controller.pl", data, kivi.eval_json_result);
 
 283   ns.load_all_second_rows = function() {
 
 284     var rows = $('.row_entry').filter(function(idx, elt) {
 
 285       return $(elt).find('[name="second_row"]').data('loaded') != 1;
 
 288     var item_ids = $.map(rows, function(elt) {
 
 289       var item_id = $(elt).find('[name="orderitem_ids[+]"]').val();
 
 290       return { name: 'item_ids[]', value: item_id };
 
 293     if (item_ids.length == 0) {
 
 297     var data = $('#order_form').serializeArray();
 
 298     data.push({ name: 'action', value: 'Order/load_second_rows' });
 
 299     data = data.concat(item_ids);
 
 301     $.post("controller.pl", data, kivi.eval_json_result);
 
 304   ns.hide_second_row = function(row) {
 
 305     $(row).children().not(':first').hide();
 
 306     $(row).data('expanded', 0);
 
 307     var elt = $(row).find('.expand');
 
 308     elt.attr('src', "image/expand.svg");
 
 309     elt.attr('alt', kivi.t8('Show details'));
 
 310     elt.attr('title', kivi.t8('Show details'));
 
 313   ns.show_second_row = function(row) {
 
 314     $(row).children().not(':first').show();
 
 315     $(row).data('expanded', 1);
 
 316     var elt = $(row).find('.expand');
 
 317     elt.attr('src', "image/collapse.svg");
 
 318     elt.attr('alt', kivi.t8('Hide details'));
 
 319     elt.attr('title', kivi.t8('Hide details'));
 
 322   ns.toggle_second_row = function(row) {
 
 323     if ($(row).data('expanded') == 1) {
 
 324       ns.hide_second_row(row);
 
 326       ns.show_second_row(row);
 
 330   ns.init_row_handlers = function() {
 
 331     kivi.run_once_for('.recalc', 'on_change_recalc', function(elt) {
 
 332       $(elt).change(ns.recalc_amounts_and_taxes);
 
 335     kivi.run_once_for('.reformat_number', 'on_change_reformat', function(elt) {
 
 336       $(elt).change(ns.reformat_number);
 
 339     kivi.run_once_for('.unitselect', 'on_change_unit_with_oldval', function(elt) {
 
 340       $(elt).data('oldval', $(elt).val());
 
 341       $(elt).change(ns.unit_change);
 
 344     kivi.run_once_for('.row_entry', 'on_kbd_click_show_hide', function(elt) {
 
 345       $(elt).keydown(function(event) {
 
 347         if (event.keyCode == 40 && event.shiftKey === true) {
 
 349           event.preventDefault();
 
 350           row = $(event.target).parents(".row_entry").first();
 
 351           ns.load_second_row(row);
 
 352           ns.show_second_row(row);
 
 355         if (event.keyCode == 38 && event.shiftKey === true) {
 
 357           event.preventDefault();
 
 358           row = $(event.target).parents(".row_entry").first();
 
 359           ns.hide_second_row(row);
 
 365     kivi.run_once_for('.expand', 'expand_second_row', function(elt) {
 
 366       $(elt).click(function(event) {
 
 367         event.preventDefault();
 
 368         var row = $(event.target).parents(".row_entry").first();
 
 369         ns.load_second_row(row);
 
 370         ns.toggle_second_row(row);
 
 377   ns.redisplay_line_values = function(is_sales, data) {
 
 378     $('.row_entry').each(function(idx, elt) {
 
 379       $(elt).find('[name="linetotal"]').html(data[idx][0]);
 
 380       if (is_sales && $(elt).find('[name="second_row"]').data('loaded') == 1) {
 
 381         var mt = data[idx][1];
 
 382         var mp = data[idx][2];
 
 384         if (mt[0] === '-') h += ' class="plus0"';
 
 385         h += '>' + mt + '  ' + mp + '%';
 
 387         $(elt).find('[name="linemargin"]').html(h);
 
 392   ns.redisplay_cvpartnumbers = function(data) {
 
 393     $('.row_entry').each(function(idx, elt) {
 
 394       $(elt).find('[name="cvpartnumber"]').html(data[idx][0]);
 
 398   ns.renumber_positions = function() {
 
 399     $('.row_entry [name="position"]').each(function(idx, elt) {
 
 402     $('.row_entry').each(function(idx, elt) {
 
 403       $(elt).data("position", idx+1);
 
 407   ns.reorder_items = function(order_by) {
 
 408     var dir = $('#' + order_by + '_header_id a img').attr("data-sort-dir");
 
 409     $('#row_table_id thead a img').remove();
 
 414       src = "image/up.png";
 
 417       src = "image/down.png";
 
 420     $('#' + order_by + '_header_id a').append('<img border=0 data-sort-dir=' + dir + ' src=' + src + ' alt="' + kivi.t8('sort items') + '">');
 
 422     var data = $('#order_form').serializeArray();
 
 423     data.push({ name: 'action',   value: 'Order/reorder_items' },
 
 424               { name: 'order_by', value: order_by              },
 
 425               { name: 'sort_dir', value: dir                   });
 
 427     $.post("controller.pl", data, kivi.eval_json_result);
 
 430   ns.redisplay_items = function(data) {
 
 431     var old_rows = $('.row_entry').detach();
 
 433     $(data).each(function(idx, elt) {
 
 434       new_rows.push(old_rows[elt.old_pos - 1]);
 
 436     $(new_rows).appendTo($('#row_table_id'));
 
 437     ns.renumber_positions();
 
 440   ns.get_insert_before_item_id = function(wanted_pos) {
 
 441     if (wanted_pos === '') return;
 
 443     var insert_before_item_id;
 
 444     // selection by data does not seem to work if data is changed at runtime
 
 445     // var elt = $('.row_entry [data-position="' + wanted_pos + '"]');
 
 446     $('.row_entry').each(function(idx, elt) {
 
 447       if ($(elt).data("position") == wanted_pos) {
 
 448         insert_before_item_id = $(elt).find('[name="orderitem_ids[+]"]').val();
 
 453     return insert_before_item_id;
 
 456   ns.add_item = function() {
 
 457     if ($('#add_item_parts_id').val() === '') return;
 
 458     if (!ns.check_cv()) return;
 
 460     $('#row_table_id thead a img').remove();
 
 462     var insert_before_item_id = ns.get_insert_before_item_id($('#add_item_position').val());
 
 464     var data = $('#order_form').serializeArray();
 
 465     data.push({ name: 'action', value: 'Order/add_item' },
 
 466               { name: 'insert_before_item_id', value: insert_before_item_id });
 
 468     $.post("controller.pl", data, kivi.eval_json_result);
 
 471   ns.open_multi_items_dialog = function() {
 
 472     if (!ns.check_cv()) return;
 
 474     var pp = $("#add_item_parts_id").data("part_picker");
 
 479   ns.add_multi_items = function(data) {
 
 480     var insert_before_item_id = ns.get_insert_before_item_id($('#multi_items_position').val());
 
 481     data = data.concat($('#order_form').serializeArray());
 
 482     data.push({ name: 'action', value: 'Order/add_multi_items' },
 
 483               { name: 'insert_before_item_id', value: insert_before_item_id });
 
 484     $.post("controller.pl", data, kivi.eval_json_result);
 
 487   ns.delete_order_item_row = function(clicked) {
 
 488     var row = $(clicked).parents("tbody").first();
 
 491     ns.renumber_positions();
 
 492     ns.recalc_amounts_and_taxes();
 
 495   ns.row_table_scroll_down = function() {
 
 496     $('#row_table_scroll_id').scrollTop($('#row_table_scroll_id')[0].scrollHeight);
 
 499   ns.show_longdescription_dialog = function(clicked) {
 
 500     var row                 = $(clicked).parents("tbody").first();
 
 501     var position            = $(row).find('[name="position"]').html();
 
 502     var partnumber          = $(row).find('[name="partnumber"]').html();
 
 503     var description_elt     = $(row).find('[name="order.orderitems[].description"]');
 
 504     var longdescription_elt = $(row).find('[name="order.orderitems[].longdescription"]');
 
 507       runningnumber:           position,
 
 508       partnumber:              partnumber,
 
 509       description:             description_elt.val(),
 
 510       default_longdescription: longdescription_elt.val(),
 
 511       set_function:            function(val) {
 
 512         longdescription_elt.val(val);
 
 516     kivi.SalesPurchase.edit_longdescription_with_params(params);
 
 519   ns.price_chooser_item_row = function(clicked) {
 
 520     if (!ns.check_cv()) return;
 
 521     var row         = $(clicked).parents("tbody").first();
 
 522     var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
 
 524     var data = $('#order_form').serializeArray();
 
 525     data.push({ name: 'action',  value: 'Order/price_popup' },
 
 526               { name: 'item_id', value: item_id_dom.val()   });
 
 528     $.post("controller.pl", data, kivi.eval_json_result);
 
 531   ns.update_price_source = function(item_id, source, descr, price_str, price_editable) {
 
 532     var row        = $('#item_' + item_id).parents("tbody").first();
 
 533     var source_elt = $(row).find('[name="order.orderitems[].active_price_source"]');
 
 534     var button_elt = $(row).find('[name="price_chooser_button"]');
 
 536     button_elt.val(button_elt.val().replace(/.*\|/, descr + " |"));
 
 537     source_elt.val(source);
 
 539     var editable_div_elt     = $(row).find('[name="editable_price"]');
 
 540     var not_editable_div_elt = $(row).find('[name="not_editable_price"]');
 
 541     if (price_editable == 1 && source === '') {
 
 543       $(editable_div_elt).show();
 
 544       $(not_editable_div_elt).hide();
 
 545       $(editable_div_elt).find(':input').prop("disabled", false);
 
 546       $(not_editable_div_elt).find(':input').prop("disabled", true);
 
 549       $(editable_div_elt).hide();
 
 550       $(not_editable_div_elt).show();
 
 551       $(editable_div_elt).find(':input').prop("disabled", true);
 
 552       $(not_editable_div_elt).find(':input').prop("disabled", false);
 
 556       var price_elt = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
 
 557       var html_elt  = $(row).find('[name="sellprice_text"]');
 
 558       price_elt.val(price_str);
 
 559       html_elt.html(price_str);
 
 560       ns.recalc_amounts_and_taxes();
 
 563     kivi.io.close_dialog();
 
 566   ns.update_discount_source = function(item_id, source, descr, discount_str, price_editable) {
 
 567     var row        = $('#item_' + item_id).parents("tbody").first();
 
 568     var source_elt = $(row).find('[name="order.orderitems[].active_discount_source"]');
 
 569     var button_elt = $(row).find('[name="price_chooser_button"]');
 
 571     button_elt.val(button_elt.val().replace(/\|.*/, "| " + descr));
 
 572     source_elt.val(source);
 
 574     var editable_div_elt     = $(row).find('[name="editable_discount"]');
 
 575     var not_editable_div_elt = $(row).find('[name="not_editable_discount"]');
 
 576     if (price_editable == 1 && source === '') {
 
 578       $(editable_div_elt).show();
 
 579       $(not_editable_div_elt).hide();
 
 580       $(editable_div_elt).find(':input').prop("disabled", false);
 
 581       $(not_editable_div_elt).find(':input').prop("disabled", true);
 
 584       $(editable_div_elt).hide();
 
 585       $(not_editable_div_elt).show();
 
 586       $(editable_div_elt).find(':input').prop("disabled", true);
 
 587       $(not_editable_div_elt).find(':input').prop("disabled", false);
 
 591       var discount_elt = $(row).find('[name="order.orderitems[].discount_as_percent"]');
 
 592       var html_elt     = $(row).find('[name="discount_text"]');
 
 593       discount_elt.val(discount_str);
 
 594       html_elt.html(discount_str);
 
 595       ns.recalc_amounts_and_taxes();
 
 598     kivi.io.close_dialog();
 
 601   ns.show_periodic_invoices_config_dialog = function() {
 
 602     if ($('#type').val() !== 'sales_order') return;
 
 605       url:    'controller.pl?action=Order/show_periodic_invoices_config_dialog',
 
 606       data:   { type:              $('#type').val(),
 
 608                 config:            $('#order_periodic_invoices_config').val(),
 
 609                 customer_id:       $('#order_customer_id').val(),
 
 610                 transdate_as_date: $('#order_transdate_as_date').val(),
 
 611                 language_id:       $('#language_id').val()
 
 613       id:     'jq_periodic_invoices_config_dialog',
 
 614       load:   kivi.reinit_widgets,
 
 616         title:  kivi.t8('Edit the configuration for periodic invoices'),
 
 624   ns.close_periodic_invoices_config_dialog = function() {
 
 625     $('#jq_periodic_invoices_config_dialog').dialog('close');
 
 628   ns.assign_periodic_invoices_config = function() {
 
 629     var data = $('[name="Form"]').serializeArray();
 
 630     data.push({ name: 'type',   value: $('#type').val() },
 
 631               { name: 'action', value: 'Order/assign_periodic_invoices_config' });
 
 632     $.post("controller.pl", data, kivi.eval_json_result);
 
 635   ns.check_save_active_periodic_invoices = function() {
 
 636     var type = $('#type').val();
 
 637     if (type !== 'sales_order') return true;
 
 641       url:      'controller.pl',
 
 642       data:     { action: 'Order/get_has_active_periodic_invoices',
 
 645                   config: $('#order_periodic_invoices_config').val(),
 
 650       success:  function(val) {
 
 656       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?'));
 
 662   ns.show_vc_details_dialog = function() {
 
 663     if (!ns.check_cv()) return;
 
 667     if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
 
 669       vc_id = $('#order_customer_id').val();
 
 670       title = kivi.t8('Customer details');
 
 673       vc_id = $('#order_vendor_id').val();
 
 674       title = kivi.t8('Vendor details');
 
 678       url:    'controller.pl',
 
 679       data:   { action: 'Order/show_customer_vendor_details_dialog',
 
 680                 type  : $('#type').val(),
 
 684       id:     'jq_customer_vendor_details_dialog',
 
 694   ns.update_row_from_master_data = function(clicked) {
 
 695     var row = $(clicked).parents("tbody").first();
 
 696     var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
 
 698     var data = $('#order_form').serializeArray();
 
 699     data.push({ name: 'action', value: 'Order/update_row_from_master_data' });
 
 700     data.push({ name: 'item_ids[]', value: item_id_dom.val() });
 
 702     $.post("controller.pl", data, kivi.eval_json_result);
 
 705   ns.update_all_rows_from_master_data = function() {
 
 706     var item_ids = $.map($('.row_entry'), function(elt) {
 
 707       var item_id = $(elt).find('[name="orderitem_ids[+]"]').val();
 
 708       return { name: 'item_ids[]', value: item_id };
 
 711     if (item_ids.length == 0) {
 
 715     var data = $('#order_form').serializeArray();
 
 716     data.push({ name: 'action', value: 'Order/update_row_from_master_data' });
 
 717     data = data.concat(item_ids);
 
 719     $.post("controller.pl", data, kivi.eval_json_result);
 
 722   ns.show_calculate_qty_dialog = function(clicked) {
 
 723     var row        = $(clicked).parents("tbody").first();
 
 724     var input_id   = $(row).find('[name="order.orderitems[].qty_as_number"]').attr('id');
 
 725     var formula_id = $(row).find('[name="formula[+]"]').attr('id');
 
 727     calculate_qty_selection_dialog("", input_id, "", formula_id);
 
 731   ns.edit_custom_shipto = function() {
 
 732     if (!ns.check_cv()) return;
 
 734     kivi.SalesPurchase.edit_custom_shipto();
 
 737   ns.purchase_order_check_for_direct_delivery = function() {
 
 738     if ($('#type').val() != 'sales_order') {
 
 739       kivi.submit_form_with_action($('#order_form'), 'Order/purchase_order');
 
 744     if ($('#order_shipto_id').val() !== '') {
 
 746       shipto = $('#order_shipto_id option:selected').text();
 
 748       $('#shipto_inputs [id^="shipto"]').each(function(idx, elt) {
 
 749         if (!empty)                                     return true;
 
 750         if (/^shipto_to_copy/.test($(elt).prop('id')))  return true;
 
 751         if (/^shiptocp_gender/.test($(elt).prop('id'))) return true;
 
 752         if (/^shiptocvar_/.test($(elt).prop('id')))     return true;
 
 753         if ($(elt).val() !== '') {
 
 758       var shipto_elements = [];
 
 759       $([$('#shiptoname').val(), $('#shiptostreet').val(), $('#shiptozipcode').val(), $('#shiptocity').val()]).each(function(idx, elt) {
 
 760         if (elt !== '') shipto_elements.push(elt);
 
 762       shipto = shipto_elements.join('; ');
 
 767       ns.direct_delivery_dialog(shipto);
 
 769       kivi.submit_form_with_action($('#order_form'), 'Order/purchase_order');
 
 773   ns.direct_delivery_callback = function(accepted) {
 
 774     $('#direct-delivery-dialog').dialog('close');
 
 777       $('<input type="hidden" name="use_shipto">').appendTo('#order_form').val('1');
 
 780     kivi.submit_form_with_action($('#order_form'), 'Order/purchase_order');
 
 783   ns.direct_delivery_dialog = function(shipto) {
 
 784     $('#direct-delivery-dialog').remove();
 
 786     var text1 = kivi.t8('You have entered or selected the following shipping address for this customer:');
 
 787     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?');
 
 788     var html  = '<div id="direct-delivery-dialog"><p>' + text1 + '</p><p>' + shipto + '</p><p>' + text2 + '</p>';
 
 789     html      = html + '<hr><p>';
 
 790     html      = html + '<input type="button" value="' + kivi.t8('Yes') + '" size="30" onclick="kivi.Order.direct_delivery_callback(true)">';
 
 791     html      = html + ' ';
 
 792     html      = html + '<input type="button" value="' + kivi.t8('No')  + '" size="30" onclick="kivi.Order.direct_delivery_callback(false)">';
 
 793     html      = html + '</p></div>';
 
 794     $(html).hide().appendTo('#order_form');
 
 796     kivi.popup_dialog({id: 'direct-delivery-dialog',
 
 797                        dialog: {title:  kivi.t8('Carry over shipping address'),
 
 802   ns.follow_up_window = function() {
 
 803     var id   = $('#id').val();
 
 804     var type = $('#type').val();
 
 806     var number_info = '';
 
 807     if ($('#type').val() == 'sales_order' || $('#type').val() == 'purchase_order') {
 
 808       number_info = $('#order_ordnumber').val();
 
 809     } else if ($('#type').val() == 'sales_quotation' || $('#type').val() == 'request_quotation') {
 
 810       number_info = $('#order_quonumber').val();
 
 814     if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation') {
 
 815       name_info = $('#order_customer_id_name').val();
 
 816     } else if ($('#type').val() == 'purchase_order' || $('#type').val() == 'request_quotation') {
 
 817       name_info = $('#order_vendor_id_name').val();
 
 821     if (number_info !== '') { info += ' (' + number_info + ')' }
 
 822     if (name_info   !== '') { info += ' (' + name_info + ')' }
 
 824     if (!$('#follow_up_rowcount').lenght) {
 
 825       $('<input type="hidden" name="follow_up_rowcount"        id="follow_up_rowcount">').appendTo('#order_form');
 
 826       $('<input type="hidden" name="follow_up_trans_id_1"      id="follow_up_trans_id_1">').appendTo('#order_form');
 
 827       $('<input type="hidden" name="follow_up_trans_type_1"    id="follow_up_trans_type_1">').appendTo('#order_form');
 
 828       $('<input type="hidden" name="follow_up_trans_info_1"    id="follow_up_trans_info_1">').appendTo('#order_form');
 
 829       $('<input type="hidden" name="follow_up_trans_subject_1" id="follow_up_trans_subject_1">').appendTo('#order_form');
 
 831     $('#follow_up_rowcount').val(1);
 
 832     $('#follow_up_trans_id_1').val(id);
 
 833     $('#follow_up_trans_type_1').val(type);
 
 834     $('#follow_up_trans_info_1').val(info);
 
 835     $('#follow_up_trans_subject_1').val($('#order_transaction_description').val());
 
 840   ns.create_part = function() {
 
 841     var data = $('#order_form').serializeArray();
 
 842     data.push({ name: 'action', value: 'Order/create_part' });
 
 844     $.post("controller.pl", data, kivi.eval_json_result);
 
 850   if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
 
 851     $('#order_customer_id').change(kivi.Order.reload_cv_dependent_selections);
 
 853     $('#order_vendor_id').change(kivi.Order.reload_cv_dependent_selections);
 
 856   $('#order_currency_id').change(kivi.Order.update_exchangerate);
 
 857   $('#order_transdate_as_date').change(kivi.Order.update_exchangerate);
 
 858   $('#order_exchangerate_as_null_number').change(kivi.Order.exchangerate_changed);
 
 860   if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
 
 861     $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_sellprice_as_number').val(kivi.format_amount(o.sellprice, -2)) });
 
 863     $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_sellprice_as_number').val(kivi.format_amount(o.lastcost, -2)) });
 
 865   $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_description').val(o.description) });
 
 866   $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_unit').val(o.unit) });
 
 868   $('.add_item_input').keydown(function(event) {
 
 869     if (event.keyCode == 13) {
 
 870       event.preventDefault();
 
 871       kivi.Order.add_item();
 
 876   kivi.Order.init_row_handlers();
 
 878   $('#row_table_id').on('sortstop', function(event, ui) {
 
 879     $('#row_table_id thead a img').remove();
 
 880     kivi.Order.renumber_positions();
 
 883   $('#expand_all').on('click', function(event) {
 
 884     event.preventDefault();
 
 885     if ($('#expand_all').data('expanded') == 1) {
 
 886       $('#expand_all').data('expanded', 0);
 
 887       $('#expand_all').attr('src', 'image/expand.svg');
 
 888       $('#expand_all').attr('alt', kivi.t8('Show all details'));
 
 889       $('#expand_all').attr('title', kivi.t8('Show all details'));
 
 890       $('.row_entry').each(function(idx, elt) {
 
 891         kivi.Order.hide_second_row(elt);
 
 894       $('#expand_all').data('expanded', 1);
 
 895       $('#expand_all').attr('src', "image/collapse.svg");
 
 896       $('#expand_all').attr('alt', kivi.t8('Hide all details'));
 
 897       $('#expand_all').attr('title', kivi.t8('Hide all details'));
 
 898       kivi.Order.load_all_second_rows();
 
 899       $('.row_entry').each(function(idx, elt) {
 
 900         kivi.Order.show_second_row(elt);
 
 906   $('.reformat_number_as_null_number').change(kivi.Order.reformat_number_as_null_number);