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