Auftrags-Controller: Artikel-Mehrfachauswahl auf die des PartPickers umgestellt
[kivitendo-erp.git] / js / kivi.Order.js
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.'));
6         return false;
7       }
8     } else  {
9       if ($('#order_vendor_id').val() === '') {
10         alert(kivi.t8('Please select a vendor.'));
11         return false;
12       }
13     }
14     return true;
15   };
16
17   ns.check_duplicate_parts = function(question) {
18     var id_arr = $('[name="order.orderitems[].parts_id"]').map(function() { return this.value; }).get();
19
20     var i, obj = {}, pos = [];
21
22     for (i = 0; i < id_arr.length; i++) {
23       var id = id_arr[i];
24       if (obj.hasOwnProperty(id)) {
25         pos.push(i + 1);
26       }
27       obj[id] = 0;
28     }
29
30     if (pos.length > 0) {
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"
34                      + question);
35     }
36     return true;
37   };
38
39   ns.check_valid_reqdate = function() {
40     if ($('#order_reqdate_as_date').val() === '') {
41       alert(kivi.t8('Please select a delivery date.'));
42       return false;
43     } else {
44       return true;
45     }
46   };
47
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;
52
53     var data = $('#order_form').serializeArray();
54     data.push({ name: 'action', value: 'Order/' + action });
55
56     $.post("controller.pl", data, kivi.eval_json_result);
57   };
58
59   ns.delete_order = function() {
60     var data = $('#order_form').serializeArray();
61     data.push({ name: 'action', value: 'Order/delete' });
62
63     $.post("controller.pl", data, kivi.eval_json_result);
64   };
65
66   ns.show_print_options = function(warn_on_duplicates) {
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
70     kivi.popup_dialog({
71       id: 'print_options',
72       dialog: {
73         title: kivi.t8('Print options'),
74         width:  800,
75         height: 300
76       }
77     });
78   };
79
80   ns.print = function() {
81     $('#print_options').dialog('close');
82
83     var data = $('#order_form').serializeArray();
84     data = data.concat($('#print_options_form').serializeArray());
85     data.push({ name: 'action', value: 'Order/print' });
86
87     $.post("controller.pl", data, kivi.eval_json_result);
88   };
89
90   var email_dialog;
91
92   ns.setup_send_email_dialog = function() {
93     kivi.SalesPurchase.show_all_print_options_elements();
94     kivi.SalesPurchase.show_print_options_elements([ 'sendmode', 'media', 'copies', 'remove_draft' ], false);
95
96     $('#print_options_form table').first().remove().appendTo('#email_form_print_options');
97
98     var to_focus = $('#email_form_to').val() === '' ? 'to' : 'subject';
99     $('#email_form_' + to_focus).focus();
100   };
101
102   ns.finish_send_email_dialog = function() {
103     kivi.SalesPurchase.show_all_print_options_elements();
104
105     $('#email_form_print_options table').first().remove().prependTo('#print_options_form');
106     return true;
107   };
108
109   ns.show_email_dialog = function(html) {
110     var id            = 'send_email_dialog';
111     var dialog_params = {
112       id:     id,
113       width:  800,
114       height: 600,
115       title:  kivi.t8('Send email'),
116       modal:  true,
117       beforeClose: kivi.Order.finish_send_email_dialog,
118       close: function(event, ui) {
119         email_dialog.remove();
120       }
121     };
122
123     $('#' + id).remove();
124
125     email_dialog = $('<div style="display:none" id="' + id + '"></div>').appendTo('body');
126     email_dialog.html(html);
127     email_dialog.dialog(dialog_params);
128
129     kivi.Order.setup_send_email_dialog();
130
131     $('.cancel').click(ns.close_email_dialog);
132
133     return true;
134   };
135
136   ns.send_email = function() {
137     var data = $('#order_form').serializeArray();
138     data = data.concat($('[name^="email_form."]').serializeArray());
139     data = data.concat($('[name^="print_options."]').serializeArray());
140     data.push({ name: 'action', value: 'Order/send_email' });
141     $.post("controller.pl", data, kivi.eval_json_result);
142   };
143
144   ns.close_email_dialog = function() {
145     email_dialog.dialog("close");
146   };
147
148   ns.set_number_in_title = function(elt) {
149     $('#nr_in_title').html($(elt).val());
150   };
151
152   ns.reload_cv_dependent_selections = function() {
153     $('#order_shipto_id').val('');
154     var data = $('#order_form').serializeArray();
155     data.push({ name: 'action', value: 'Order/customer_vendor_changed' });
156
157     $.post("controller.pl", data, kivi.eval_json_result);
158   };
159
160   ns.reformat_number = function(event) {
161     $(event.target).val(kivi.format_amount(kivi.parse_amount($(event.target).val()), -2));
162   };
163
164   ns.reformat_number_as_null_number = function(event) {
165     if ($(event.target).val() === '') {
166       return;
167     }
168     ns.reformat_number(event);
169   };
170
171   ns.update_exchangerate = function(event) {
172     if (!ns.check_cv()) {
173       $('#order_currency_id').val($('#old_currency_id').val());
174       return;
175     }
176
177     var rate_input = $('#order_exchangerate_as_null_number');
178     // unset exchangerate if currency changed
179     if ($('#order_currency_id').val() !== $('#old_currency_id').val()) {
180       rate_input.val('');
181     }
182
183     // only set exchangerate if unset
184     if (rate_input.val() !== '') {
185       return;
186     }
187
188     var data = $('#order_form').serializeArray();
189     data.push({ name: 'action', value: 'Order/update_exchangerate' });
190
191     $.ajax({
192       url: 'controller.pl',
193       data: data,
194       method: 'POST',
195       dataType: 'json',
196       success: function(data){
197         if (!data.is_standard) {
198           $('#currency_name').text(data.currency_name);
199           if (data.exchangerate) {
200             rate_input.val(data.exchangerate);
201           } else {
202             rate_input.val('');
203           }
204           $('#exchangerate_settings').show();
205         } else {
206           rate_input.val('');
207           $('#exchangerate_settings').hide();
208         }
209         if ($('#order_currency_id').val() != $('#old_currency_id').val() ||
210             !data.is_standard && data.exchangerate != $('#old_exchangerate').val()) {
211           kivi.display_flash('warning', kivi.t8('You have changed the currency or exchange rate. Please check prices.'));
212         }
213         $('#old_currency_id').val($('#order_currency_id').val());
214         $('#old_exchangerate').val(data.exchangerate);
215       }
216     });
217   };
218
219   ns.exchangerate_changed = function(event) {
220     if (kivi.parse_amount($('#order_exchangerate_as_null_number').val()) != kivi.parse_amount($('#old_exchangerate').val())) {
221       kivi.display_flash('warning', kivi.t8('You have changed the currency or exchange rate. Please check prices.'));
222       $('#old_exchangerate').val($('#order_exchangerate_as_null_number').val());
223     }
224   };
225
226   ns.recalc_amounts_and_taxes = function() {
227     var data = $('#order_form').serializeArray();
228     data.push({ name: 'action', value: 'Order/recalc_amounts_and_taxes' });
229
230     $.post("controller.pl", data, kivi.eval_json_result);
231   };
232
233   ns.unit_change = function(event) {
234     var row           = $(event.target).parents("tbody").first();
235     var item_id_dom   = $(row).find('[name="orderitem_ids[+]"]');
236     var sellprice_dom = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
237     var select_elt    = $(row).find('[name="order.orderitems[].unit"]');
238
239     var oldval = $(select_elt).data('oldval');
240     $(select_elt).data('oldval', $(select_elt).val());
241
242     var data = $('#order_form').serializeArray();
243     data.push({ name: 'action',           value: 'Order/unit_changed'     },
244               { name: 'item_id',          value: item_id_dom.val()        },
245               { name: 'old_unit',         value: oldval                   },
246               { name: 'sellprice_dom_id', value: sellprice_dom.attr('id') });
247
248     $.post("controller.pl", data, kivi.eval_json_result);
249   };
250
251   ns.update_sellprice = function(item_id, price_str) {
252     var row       = $('#item_' + item_id).parents("tbody").first();
253     var price_elt = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
254     var html_elt  = $(row).find('[name="sellprice_text"]');
255     price_elt.val(price_str);
256     html_elt.html(price_str);
257   };
258
259   ns.load_second_row = function(row) {
260     var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
261     var div_elt     = $(row).find('[name="second_row"]');
262
263     if ($(div_elt).data('loaded') == 1) {
264       return;
265     }
266     var data = $('#order_form').serializeArray();
267     data.push({ name: 'action',     value: 'Order/load_second_rows' },
268               { name: 'item_ids[]', value: item_id_dom.val()        });
269
270     $.post("controller.pl", data, kivi.eval_json_result);
271   };
272
273   ns.load_all_second_rows = function() {
274     var rows = $('.row_entry').filter(function(idx, elt) {
275       return $(elt).find('[name="second_row"]').data('loaded') != 1;
276     });
277
278     var item_ids = $.map(rows, function(elt) {
279       var item_id = $(elt).find('[name="orderitem_ids[+]"]').val();
280       return { name: 'item_ids[]', value: item_id };
281     });
282
283     if (item_ids.length == 0) {
284       return;
285     }
286
287     var data = $('#order_form').serializeArray();
288     data.push({ name: 'action', value: 'Order/load_second_rows' });
289     data = data.concat(item_ids);
290
291     $.post("controller.pl", data, kivi.eval_json_result);
292   };
293
294   ns.hide_second_row = function(row) {
295     $(row).children().not(':first').hide();
296     $(row).data('expanded', 0);
297     var elt = $(row).find('.expand');
298     elt.attr('src', "image/expand.svg");
299     elt.attr('alt', kivi.t8('Show details'));
300     elt.attr('title', kivi.t8('Show details'));
301   };
302
303   ns.show_second_row = function(row) {
304     $(row).children().not(':first').show();
305     $(row).data('expanded', 1);
306     var elt = $(row).find('.expand');
307     elt.attr('src', "image/collapse.svg");
308     elt.attr('alt', kivi.t8('Hide details'));
309     elt.attr('title', kivi.t8('Hide details'));
310   };
311
312   ns.toggle_second_row = function(row) {
313     if ($(row).data('expanded') == 1) {
314       ns.hide_second_row(row);
315     } else {
316       ns.show_second_row(row);
317     }
318   };
319
320   ns.init_row_handlers = function() {
321     kivi.run_once_for('.recalc', 'on_change_recalc', function(elt) {
322       $(elt).change(ns.recalc_amounts_and_taxes);
323     });
324
325     kivi.run_once_for('.reformat_number', 'on_change_reformat', function(elt) {
326       $(elt).change(ns.reformat_number);
327     });
328
329     kivi.run_once_for('.unitselect', 'on_change_unit_with_oldval', function(elt) {
330       $(elt).data('oldval', $(elt).val());
331       $(elt).change(ns.unit_change);
332     });
333
334     kivi.run_once_for('.row_entry', 'on_kbd_click_show_hide', function(elt) {
335       $(elt).keydown(function(event) {
336         var row;
337         if (event.keyCode == 40 && event.shiftKey === true) {
338           // shift arrow down
339           event.preventDefault();
340           row = $(event.target).parents(".row_entry").first();
341           ns.load_second_row(row);
342           ns.show_second_row(row);
343           return false;
344         }
345         if (event.keyCode == 38 && event.shiftKey === true) {
346           // shift arrow up
347           event.preventDefault();
348           row = $(event.target).parents(".row_entry").first();
349           ns.hide_second_row(row);
350           return false;
351         }
352       });
353     });
354
355     kivi.run_once_for('.expand', 'expand_second_row', function(elt) {
356       $(elt).click(function(event) {
357         event.preventDefault();
358         var row = $(event.target).parents(".row_entry").first();
359         ns.load_second_row(row);
360         ns.toggle_second_row(row);
361         return false;
362       })
363     });
364
365   };
366
367   ns.redisplay_line_values = function(is_sales, data) {
368     $('.row_entry').each(function(idx, elt) {
369       $(elt).find('[name="linetotal"]').html(data[idx][0]);
370       if (is_sales && $(elt).find('[name="second_row"]').data('loaded') == 1) {
371         var mt = data[idx][1];
372         var mp = data[idx][2];
373         var h  = '<span';
374         if (mt[0] === '-') h += ' class="plus0"';
375         h += '>' + mt + '&nbsp;&nbsp;' + mp + '%';
376         h += '</span>';
377         $(elt).find('[name="linemargin"]').html(h);
378       }
379     });
380   };
381
382   ns.redisplay_cvpartnumbers = function(data) {
383     $('.row_entry').each(function(idx, elt) {
384       $(elt).find('[name="cvpartnumber"]').html(data[idx][0]);
385     });
386   };
387
388   ns.renumber_positions = function() {
389     $('.row_entry [name="position"]').each(function(idx, elt) {
390       $(elt).html(idx+1);
391     });
392     $('.row_entry').each(function(idx, elt) {
393       $(elt).data("position", idx+1);
394     });
395   };
396
397   ns.reorder_items = function(order_by) {
398     var dir = $('#' + order_by + '_header_id a img').attr("data-sort-dir");
399     $('#row_table_id thead a img').remove();
400
401     var src;
402     if (dir == "1") {
403       dir = "0";
404       src = "image/up.png";
405     } else {
406       dir = "1";
407       src = "image/down.png";
408     }
409
410     $('#' + order_by + '_header_id a').append('<img border=0 data-sort-dir=' + dir + ' src=' + src + ' alt="' + kivi.t8('sort items') + '">');
411
412     var data = $('#order_form').serializeArray();
413     data.push({ name: 'action',   value: 'Order/reorder_items' },
414               { name: 'order_by', value: order_by              },
415               { name: 'sort_dir', value: dir                   });
416
417     $.post("controller.pl", data, kivi.eval_json_result);
418   };
419
420   ns.redisplay_items = function(data) {
421     var old_rows = $('.row_entry').detach();
422     var new_rows = [];
423     $(data).each(function(idx, elt) {
424       new_rows.push(old_rows[elt.old_pos - 1]);
425     });
426     $(new_rows).appendTo($('#row_table_id'));
427     ns.renumber_positions();
428   };
429
430   ns.get_insert_before_item_id = function(wanted_pos) {
431     if (wanted_pos === '') return;
432
433     var insert_before_item_id;
434     // selection by data does not seem to work if data is changed at runtime
435     // var elt = $('.row_entry [data-position="' + wanted_pos + '"]');
436     $('.row_entry').each(function(idx, elt) {
437       if ($(elt).data("position") == wanted_pos) {
438         insert_before_item_id = $(elt).find('[name="orderitem_ids[+]"]').val();
439         return false;
440       }
441     });
442
443     return insert_before_item_id;
444   };
445
446   ns.add_item = function() {
447     if ($('#add_item_parts_id').val() === '') return;
448     if (!ns.check_cv()) return;
449
450     $('#row_table_id thead a img').remove();
451
452     var insert_before_item_id = ns.get_insert_before_item_id($('#add_item_position').val());
453
454     var data = $('#order_form').serializeArray();
455     data.push({ name: 'action', value: 'Order/add_item' },
456               { name: 'insert_before_item_id', value: insert_before_item_id });
457
458     $.post("controller.pl", data, kivi.eval_json_result);
459   };
460
461   ns.add_multi_items = function(data) {
462     var insert_before_item_id = ns.get_insert_before_item_id($('#multi_items_position').val());
463     data = data.concat($('#order_form').serializeArray());
464     data.push({ name: 'action', value: 'Order/add_multi_items' },
465               { name: 'insert_before_item_id', value: insert_before_item_id });
466     $.post("controller.pl", data, kivi.eval_json_result);
467   };
468
469   ns.delete_order_item_row = function(clicked) {
470     var row = $(clicked).parents("tbody").first();
471     $(row).remove();
472
473     ns.renumber_positions();
474     ns.recalc_amounts_and_taxes();
475   };
476
477   ns.row_table_scroll_down = function() {
478     $('#row_table_scroll_id').scrollTop($('#row_table_scroll_id')[0].scrollHeight);
479   };
480
481   ns.show_longdescription_dialog = function(clicked) {
482     var row                 = $(clicked).parents("tbody").first();
483     var position            = $(row).find('[name="position"]').html();
484     var partnumber          = $(row).find('[name="partnumber"]').html();
485     var description_elt     = $(row).find('[name="order.orderitems[].description"]');
486     var longdescription_elt = $(row).find('[name="order.orderitems[].longdescription"]');
487
488     var params = {
489       runningnumber:           position,
490       partnumber:              partnumber,
491       description:             description_elt.val(),
492       default_longdescription: longdescription_elt.val(),
493       set_function:            function(val) {
494         longdescription_elt.val(val);
495       }
496     };
497
498     kivi.SalesPurchase.edit_longdescription_with_params(params);
499   };
500
501   ns.price_chooser_item_row = function(clicked) {
502     if (!ns.check_cv()) return;
503     var row         = $(clicked).parents("tbody").first();
504     var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
505
506     var data = $('#order_form').serializeArray();
507     data.push({ name: 'action',  value: 'Order/price_popup' },
508               { name: 'item_id', value: item_id_dom.val()   });
509
510     $.post("controller.pl", data, kivi.eval_json_result);
511   };
512
513   ns.update_price_source = function(item_id, source, descr, price_str, price_editable) {
514     var row        = $('#item_' + item_id).parents("tbody").first();
515     var source_elt = $(row).find('[name="order.orderitems[].active_price_source"]');
516     var button_elt = $(row).find('[name="price_chooser_button"]');
517
518     button_elt.val(button_elt.val().replace(/.*\|/, descr + " |"));
519     source_elt.val(source);
520
521     var editable_div_elt     = $(row).find('[name="editable_price"]');
522     var not_editable_div_elt = $(row).find('[name="not_editable_price"]');
523     if (price_editable == 1 && source === '') {
524       // editable
525       $(editable_div_elt).show();
526       $(not_editable_div_elt).hide();
527       $(editable_div_elt).find(':input').prop("disabled", false);
528       $(not_editable_div_elt).find(':input').prop("disabled", true);
529     } else {
530       // not editable
531       $(editable_div_elt).hide();
532       $(not_editable_div_elt).show();
533       $(editable_div_elt).find(':input').prop("disabled", true);
534       $(not_editable_div_elt).find(':input').prop("disabled", false);
535     }
536
537     if (price_str) {
538       var price_elt = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
539       var html_elt  = $(row).find('[name="sellprice_text"]');
540       price_elt.val(price_str);
541       html_elt.html(price_str);
542       ns.recalc_amounts_and_taxes();
543     }
544
545     kivi.io.close_dialog();
546   };
547
548   ns.update_discount_source = function(item_id, source, descr, discount_str, price_editable) {
549     var row        = $('#item_' + item_id).parents("tbody").first();
550     var source_elt = $(row).find('[name="order.orderitems[].active_discount_source"]');
551     var button_elt = $(row).find('[name="price_chooser_button"]');
552
553     button_elt.val(button_elt.val().replace(/\|.*/, "| " + descr));
554     source_elt.val(source);
555
556     var editable_div_elt     = $(row).find('[name="editable_discount"]');
557     var not_editable_div_elt = $(row).find('[name="not_editable_discount"]');
558     if (price_editable == 1 && source === '') {
559       // editable
560       $(editable_div_elt).show();
561       $(not_editable_div_elt).hide();
562       $(editable_div_elt).find(':input').prop("disabled", false);
563       $(not_editable_div_elt).find(':input').prop("disabled", true);
564     } else {
565       // not editable
566       $(editable_div_elt).hide();
567       $(not_editable_div_elt).show();
568       $(editable_div_elt).find(':input').prop("disabled", true);
569       $(not_editable_div_elt).find(':input').prop("disabled", false);
570     }
571
572     if (discount_str) {
573       var discount_elt = $(row).find('[name="order.orderitems[].discount_as_percent"]');
574       var html_elt     = $(row).find('[name="discount_text"]');
575       discount_elt.val(discount_str);
576       html_elt.html(discount_str);
577       ns.recalc_amounts_and_taxes();
578     }
579
580     kivi.io.close_dialog();
581   };
582
583   ns.show_periodic_invoices_config_dialog = function() {
584     if ($('#type').val() !== 'sales_order') return;
585
586     kivi.popup_dialog({
587       url:    'controller.pl?action=Order/show_periodic_invoices_config_dialog',
588       data:   { type:              $('#type').val(),
589                 id:                $('#id').val(),
590                 config:            $('#order_periodic_invoices_config').val(),
591                 customer_id:       $('#order_customer_id').val(),
592                 transdate_as_date: $('#order_transdate_as_date').val(),
593                 language_id:       $('#language_id').val()
594               },
595       id:     'jq_periodic_invoices_config_dialog',
596       load:   kivi.reinit_widgets,
597       dialog: {
598         title:  kivi.t8('Edit the configuration for periodic invoices'),
599         width:  800,
600         height: 650
601       }
602     });
603     return true;
604   };
605
606   ns.close_periodic_invoices_config_dialog = function() {
607     $('#jq_periodic_invoices_config_dialog').dialog('close');
608   };
609
610   ns.assign_periodic_invoices_config = function() {
611     var data = $('[name="Form"]').serializeArray();
612     data.push({ name: 'type',   value: $('#type').val() },
613               { name: 'action', value: 'Order/assign_periodic_invoices_config' });
614     $.post("controller.pl", data, kivi.eval_json_result);
615   };
616
617   ns.check_save_active_periodic_invoices = function() {
618     var type = $('#type').val();
619     if (type !== 'sales_order') return true;
620
621     var active = false;
622     $.ajax({
623       url:      'controller.pl',
624       data:     { action: 'Order/get_has_active_periodic_invoices',
625                   type  : type,
626                   id    : $('#id').val(),
627                   config: $('#order_periodic_invoices_config').val(),
628                 },
629       method:   "GET",
630       async:    false,
631       dataType: 'text',
632       success:  function(val) {
633         active = val;
634       }
635     });
636
637     if (active == 1) {
638       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?'));
639     }
640
641     return true;
642   };
643
644   ns.show_vc_details_dialog = function() {
645     if (!ns.check_cv()) return;
646     var vc;
647     var vc_id;
648     var title;
649     if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
650       vc    = 'customer';
651       vc_id = $('#order_customer_id').val();
652       title = kivi.t8('Customer details');
653     } else {
654       vc    = 'vendor';
655       vc_id = $('#order_vendor_id').val();
656       title = kivi.t8('Vendor details');
657     }
658
659     kivi.popup_dialog({
660       url:    'controller.pl',
661       data:   { action: 'Order/show_customer_vendor_details_dialog',
662                 type  : $('#type').val(),
663                 vc    : vc,
664                 vc_id : vc_id
665               },
666       id:     'jq_customer_vendor_details_dialog',
667       dialog: {
668         title:  title,
669         width:  800,
670         height: 650
671       }
672     });
673     return true;
674   };
675
676   ns.update_row_from_master_data = function(clicked) {
677     var row = $(clicked).parents("tbody").first();
678     var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
679
680     var data = $('#order_form').serializeArray();
681     data.push({ name: 'action', value: 'Order/update_row_from_master_data' });
682     data.push({ name: 'item_ids[]', value: item_id_dom.val() });
683
684     $.post("controller.pl", data, kivi.eval_json_result);
685   };
686
687   ns.update_all_rows_from_master_data = function() {
688     var item_ids = $.map($('.row_entry'), function(elt) {
689       var item_id = $(elt).find('[name="orderitem_ids[+]"]').val();
690       return { name: 'item_ids[]', value: item_id };
691     });
692
693     if (item_ids.length == 0) {
694       return;
695     }
696
697     var data = $('#order_form').serializeArray();
698     data.push({ name: 'action', value: 'Order/update_row_from_master_data' });
699     data = data.concat(item_ids);
700
701     $.post("controller.pl", data, kivi.eval_json_result);
702   };
703
704   ns.show_calculate_qty_dialog = function(clicked) {
705     var row        = $(clicked).parents("tbody").first();
706     var input_id   = $(row).find('[name="order.orderitems[].qty_as_number"]').attr('id');
707     var formula_id = $(row).find('[name="formula[+]"]').attr('id');
708
709     calculate_qty_selection_dialog("", input_id, "", formula_id);
710     return true;
711   };
712
713   ns.edit_custom_shipto = function() {
714     if (!ns.check_cv()) return;
715
716     kivi.SalesPurchase.edit_custom_shipto();
717   };
718
719   ns.purchase_order_check_for_direct_delivery = function() {
720     if ($('#type').val() != 'sales_order') {
721       kivi.submit_form_with_action($('#order_form'), 'Order/purchase_order');
722     }
723
724     var empty = true;
725     var shipto;
726     if ($('#order_shipto_id').val() !== '') {
727       empty = false;
728       shipto = $('#order_shipto_id option:selected').text();
729     } else {
730       $('#shipto_inputs [id^="shipto"]').each(function(idx, elt) {
731         if (!empty)                                     return true;
732         if (/^shipto_to_copy/.test($(elt).prop('id')))  return true;
733         if (/^shiptocp_gender/.test($(elt).prop('id'))) return true;
734         if (/^shiptocvar_/.test($(elt).prop('id')))     return true;
735         if ($(elt).val() !== '') {
736           empty = false;
737           return false;
738         }
739       });
740       var shipto_elements = [];
741       $([$('#shiptoname').val(), $('#shiptostreet').val(), $('#shiptozipcode').val(), $('#shiptocity').val()]).each(function(idx, elt) {
742         if (elt !== '') shipto_elements.push(elt);
743       });
744       shipto = shipto_elements.join('; ');
745     }
746
747     var use_it = false;
748     if (!empty) {
749       ns.direct_delivery_dialog(shipto);
750     } else {
751       kivi.submit_form_with_action($('#order_form'), 'Order/purchase_order');
752     }
753   };
754
755   ns.direct_delivery_callback = function(accepted) {
756     $('#direct-delivery-dialog').dialog('close');
757
758     if (accepted) {
759       $('<input type="hidden" name="use_shipto">').appendTo('#order_form').val('1');
760     }
761
762     kivi.submit_form_with_action($('#order_form'), 'Order/purchase_order');
763   };
764
765   ns.direct_delivery_dialog = function(shipto) {
766     $('#direct-delivery-dialog').remove();
767
768     var text1 = kivi.t8('You have entered or selected the following shipping address for this customer:');
769     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?');
770     var html  = '<div id="direct-delivery-dialog"><p>' + text1 + '</p><p>' + shipto + '</p><p>' + text2 + '</p>';
771     html      = html + '<hr><p>';
772     html      = html + '<input type="button" value="' + kivi.t8('Yes') + '" size="30" onclick="kivi.Order.direct_delivery_callback(true)">';
773     html      = html + '&nbsp;';
774     html      = html + '<input type="button" value="' + kivi.t8('No')  + '" size="30" onclick="kivi.Order.direct_delivery_callback(false)">';
775     html      = html + '</p></div>';
776     $(html).hide().appendTo('#order_form');
777
778     kivi.popup_dialog({id: 'direct-delivery-dialog',
779                        dialog: {title:  kivi.t8('Carry over shipping address'),
780                                 height: 300,
781                                 width:  500 }});
782   };
783
784   ns.follow_up_window = function() {
785     var id   = $('#id').val();
786     var type = $('#type').val();
787
788     var number_info = '';
789     if ($('#type').val() == 'sales_order' || $('#type').val() == 'purchase_order') {
790       number_info = $('#order_ordnumber').val();
791     } else if ($('#type').val() == 'sales_quotation' || $('#type').val() == 'request_quotation') {
792       number_info = $('#order_quonumber').val();
793     }
794
795     var name_info = '';
796     if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation') {
797       name_info = $('#order_customer_id_name').val();
798     } else if ($('#type').val() == 'purchase_order' || $('#type').val() == 'request_quotation') {
799       name_info = $('#order_vendor_id_name').val();
800     }
801
802     var info = '';
803     if (number_info !== '') { info += ' (' + number_info + ')' }
804     if (name_info   !== '') { info += ' (' + name_info + ')' }
805
806     if (!$('#follow_up_rowcount').lenght) {
807       $('<input type="hidden" name="follow_up_rowcount"        id="follow_up_rowcount">').appendTo('#order_form');
808       $('<input type="hidden" name="follow_up_trans_id_1"      id="follow_up_trans_id_1">').appendTo('#order_form');
809       $('<input type="hidden" name="follow_up_trans_type_1"    id="follow_up_trans_type_1">').appendTo('#order_form');
810       $('<input type="hidden" name="follow_up_trans_info_1"    id="follow_up_trans_info_1">').appendTo('#order_form');
811       $('<input type="hidden" name="follow_up_trans_subject_1" id="follow_up_trans_subject_1">').appendTo('#order_form');
812     }
813     $('#follow_up_rowcount').val(1);
814     $('#follow_up_trans_id_1').val(id);
815     $('#follow_up_trans_type_1').val(type);
816     $('#follow_up_trans_info_1').val(info);
817     $('#follow_up_trans_subject_1').val($('#order_transaction_description').val());
818
819     follow_up_window();
820   };
821
822 });
823
824 $(function() {
825   if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
826     $('#order_customer_id').change(kivi.Order.reload_cv_dependent_selections);
827   } else {
828     $('#order_vendor_id').change(kivi.Order.reload_cv_dependent_selections);
829   }
830
831   $('#order_currency_id').change(kivi.Order.update_exchangerate);
832   $('#order_transdate_as_date').change(kivi.Order.update_exchangerate);
833   $('#order_exchangerate_as_null_number').change(kivi.Order.exchangerate_changed);
834
835   if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
836     $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_sellprice_as_number').val(kivi.format_amount(o.sellprice, -2)) });
837   } else {
838     $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_sellprice_as_number').val(kivi.format_amount(o.lastcost, -2)) });
839   }
840   $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_description').val(o.description) });
841   $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_unit').val(o.unit) });
842
843   $('.add_item_input').keydown(function(event) {
844     if (event.keyCode == 13) {
845       event.preventDefault();
846       kivi.Order.add_item();
847       return false;
848     }
849   });
850
851   kivi.Order.init_row_handlers();
852
853   $('#row_table_id').on('sortstop', function(event, ui) {
854     $('#row_table_id thead a img').remove();
855     kivi.Order.renumber_positions();
856   });
857
858   $('#expand_all').on('click', function(event) {
859     event.preventDefault();
860     if ($('#expand_all').data('expanded') == 1) {
861       $('#expand_all').data('expanded', 0);
862       $('#expand_all').attr('src', 'image/expand.svg');
863       $('#expand_all').attr('alt', kivi.t8('Show all details'));
864       $('#expand_all').attr('title', kivi.t8('Show all details'));
865       $('.row_entry').each(function(idx, elt) {
866         kivi.Order.hide_second_row(elt);
867       });
868     } else {
869       $('#expand_all').data('expanded', 1);
870       $('#expand_all').attr('src', "image/collapse.svg");
871       $('#expand_all').attr('alt', kivi.t8('Hide all details'));
872       $('#expand_all').attr('title', kivi.t8('Hide all details'));
873       kivi.Order.load_all_second_rows();
874       $('.row_entry').each(function(idx, elt) {
875         kivi.Order.show_second_row(elt);
876       });
877     }
878     return false;
879   });
880
881   $('.reformat_number_as_null_number').change(kivi.Order.reformat_number_as_null_number);
882
883 });