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