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