b82358b679138fc80fb93d1e6e6a0e9af8374802
[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.update_price_source = 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       ns.recalc_amounts_and_taxes();
591     }
592
593     kivi.io.close_dialog();
594   };
595
596   ns.update_discount_source = function(item_id, source, descr, discount_str, price_editable) {
597     var row        = $('#item_' + item_id).parents("tbody").first();
598     var source_elt = $(row).find('[name="order.orderitems[].active_discount_source"]');
599     var button_elt = $(row).find('[name="price_chooser_button"]');
600
601     button_elt.val(button_elt.val().replace(/\|.*/, "| " + descr));
602     source_elt.val(source);
603
604     var editable_div_elt     = $(row).find('[name="editable_discount"]');
605     var not_editable_div_elt = $(row).find('[name="not_editable_discount"]');
606     if (price_editable == 1 && source === '') {
607       // editable
608       $(editable_div_elt).show();
609       $(not_editable_div_elt).hide();
610       $(editable_div_elt).find(':input').prop("disabled", false);
611       $(not_editable_div_elt).find(':input').prop("disabled", true);
612     } else {
613       // not editable
614       $(editable_div_elt).hide();
615       $(not_editable_div_elt).show();
616       $(editable_div_elt).find(':input').prop("disabled", true);
617       $(not_editable_div_elt).find(':input').prop("disabled", false);
618     }
619
620     if (discount_str) {
621       var discount_elt = $(row).find('[name="order.orderitems[].discount_as_percent"]');
622       var html_elt     = $(row).find('[name="discount_text"]');
623       discount_elt.val(discount_str);
624       html_elt.html(discount_str);
625       ns.recalc_amounts_and_taxes();
626     }
627
628     kivi.io.close_dialog();
629   };
630
631   ns.show_periodic_invoices_config_dialog = function() {
632     if ($('#type').val() !== 'sales_order') return;
633
634     kivi.popup_dialog({
635       url:    'controller.pl?action=Order/show_periodic_invoices_config_dialog',
636       data:   { type:              $('#type').val(),
637                 id:                $('#id').val(),
638                 config:            $('#order_periodic_invoices_config').val(),
639                 customer_id:       $('#order_customer_id').val(),
640                 transdate_as_date: $('#order_transdate_as_date').val(),
641                 language_id:       $('#language_id').val()
642               },
643       id:     'jq_periodic_invoices_config_dialog',
644       load:   kivi.reinit_widgets,
645       dialog: {
646         title:  kivi.t8('Edit the configuration for periodic invoices'),
647         width:  800,
648         height: 650
649       }
650     });
651     return true;
652   };
653
654   ns.close_periodic_invoices_config_dialog = function() {
655     $('#jq_periodic_invoices_config_dialog').dialog('close');
656   };
657
658   ns.assign_periodic_invoices_config = function() {
659     var data = $('[name="Form"]').serializeArray();
660     data.push({ name: 'type',   value: $('#type').val() },
661               { name: 'action', value: 'Order/assign_periodic_invoices_config' });
662     $.post("controller.pl", data, kivi.eval_json_result);
663   };
664
665   ns.check_save_active_periodic_invoices = function() {
666     var type = $('#type').val();
667     if (type !== 'sales_order') return true;
668
669     var active = false;
670     $.ajax({
671       url:      'controller.pl',
672       data:     { action: 'Order/get_has_active_periodic_invoices',
673                   type  : type,
674                   id    : $('#id').val(),
675                   config: $('#order_periodic_invoices_config').val(),
676                 },
677       method:   "GET",
678       async:    false,
679       dataType: 'text',
680       success:  function(val) {
681         active = val;
682       }
683     });
684
685     if (active == 1) {
686       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?'));
687     }
688
689     return true;
690   };
691
692   ns.show_vc_details_dialog = function() {
693     if (!ns.check_cv()) return;
694     var vc;
695     var vc_id;
696     var title;
697     if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
698       vc    = 'customer';
699       vc_id = $('#order_customer_id').val();
700       title = kivi.t8('Customer details');
701     } else {
702       vc    = 'vendor';
703       vc_id = $('#order_vendor_id').val();
704       title = kivi.t8('Vendor details');
705     }
706
707     kivi.popup_dialog({
708       url:    'controller.pl',
709       data:   { action: 'Order/show_customer_vendor_details_dialog',
710                 type  : $('#type').val(),
711                 vc    : vc,
712                 vc_id : vc_id
713               },
714       id:     'jq_customer_vendor_details_dialog',
715       dialog: {
716         title:  title,
717         width:  800,
718         height: 650
719       }
720     });
721     return true;
722   };
723
724   ns.update_row_from_master_data = function(clicked) {
725     var row = $(clicked).parents("tbody").first();
726     var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
727
728     var data = $('#order_form').serializeArray();
729     data.push({ name: 'action', value: 'Order/update_row_from_master_data' });
730     data.push({ name: 'item_ids[]', value: item_id_dom.val() });
731
732     $.post("controller.pl", data, kivi.eval_json_result);
733   };
734
735   ns.update_all_rows_from_master_data = function() {
736     var item_ids = $.map($('.row_entry'), function(elt) {
737       var item_id = $(elt).find('[name="orderitem_ids[+]"]').val();
738       return { name: 'item_ids[]', value: item_id };
739     });
740
741     if (item_ids.length == 0) {
742       return;
743     }
744
745     var data = $('#order_form').serializeArray();
746     data.push({ name: 'action', value: 'Order/update_row_from_master_data' });
747     data = data.concat(item_ids);
748
749     $.post("controller.pl", data, kivi.eval_json_result);
750   };
751
752   ns.show_calculate_qty_dialog = function(clicked) {
753     var row        = $(clicked).parents("tbody").first();
754     var input_id   = $(row).find('[name="order.orderitems[].qty_as_number"]').attr('id');
755     var formula_id = $(row).find('[name="formula[+]"]').attr('id');
756
757     calculate_qty_selection_dialog("", input_id, "", formula_id);
758     return true;
759   };
760
761   ns.edit_custom_shipto = function() {
762     if (!ns.check_cv()) return;
763
764     kivi.SalesPurchase.edit_custom_shipto();
765   };
766
767   ns.purchase_order_check_for_direct_delivery = function() {
768     if ($('#type').val() != 'sales_order') {
769       kivi.submit_form_with_action($('#order_form'), 'Order/purchase_order');
770     }
771
772     var empty = true;
773     var shipto;
774     if ($('#order_shipto_id').val() !== '') {
775       empty = false;
776       shipto = $('#order_shipto_id option:selected').text();
777     } else {
778       $('#shipto_inputs [id^="shipto"]').each(function(idx, elt) {
779         if (!empty)                                     return true;
780         if (/^shipto_to_copy/.test($(elt).prop('id')))  return true;
781         if (/^shiptocp_gender/.test($(elt).prop('id'))) return true;
782         if (/^shiptocvar_/.test($(elt).prop('id')))     return true;
783         if ($(elt).val() !== '') {
784           empty = false;
785           return false;
786         }
787       });
788       var shipto_elements = [];
789       $([$('#shiptoname').val(), $('#shiptostreet').val(), $('#shiptozipcode').val(), $('#shiptocity').val()]).each(function(idx, elt) {
790         if (elt !== '') shipto_elements.push(elt);
791       });
792       shipto = shipto_elements.join('; ');
793     }
794
795     var use_it = false;
796     if (!empty) {
797       ns.direct_delivery_dialog(shipto);
798     } else {
799       kivi.submit_form_with_action($('#order_form'), 'Order/purchase_order');
800     }
801   };
802
803   ns.direct_delivery_callback = function(accepted) {
804     $('#direct-delivery-dialog').dialog('close');
805
806     if (accepted) {
807       $('<input type="hidden" name="use_shipto">').appendTo('#order_form').val('1');
808     }
809
810     kivi.submit_form_with_action($('#order_form'), 'Order/purchase_order');
811   };
812
813   ns.direct_delivery_dialog = function(shipto) {
814     $('#direct-delivery-dialog').remove();
815
816     var text1 = kivi.t8('You have entered or selected the following shipping address for this customer:');
817     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?');
818     var html  = '<div id="direct-delivery-dialog"><p>' + text1 + '</p><p>' + shipto + '</p><p>' + text2 + '</p>';
819     html      = html + '<hr><p>';
820     html      = html + '<input type="button" value="' + kivi.t8('Yes') + '" size="30" onclick="kivi.Order.direct_delivery_callback(true)">';
821     html      = html + '&nbsp;';
822     html      = html + '<input type="button" value="' + kivi.t8('No')  + '" size="30" onclick="kivi.Order.direct_delivery_callback(false)">';
823     html      = html + '</p></div>';
824     $(html).hide().appendTo('#order_form');
825
826     kivi.popup_dialog({id: 'direct-delivery-dialog',
827                        dialog: {title:  kivi.t8('Carry over shipping address'),
828                                 height: 300,
829                                 width:  500 }});
830   };
831
832   ns.follow_up_window = function() {
833     var id   = $('#id').val();
834     var type = $('#type').val();
835
836     var number_info = '';
837     if ($('#type').val() == 'sales_order' || $('#type').val() == 'purchase_order') {
838       number_info = $('#order_ordnumber').val();
839     } else if ($('#type').val() == 'sales_quotation' || $('#type').val() == 'request_quotation') {
840       number_info = $('#order_quonumber').val();
841     }
842
843     var name_info = '';
844     if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation') {
845       name_info = $('#order_customer_id_name').val();
846     } else if ($('#type').val() == 'purchase_order' || $('#type').val() == 'request_quotation') {
847       name_info = $('#order_vendor_id_name').val();
848     }
849
850     var info = '';
851     if (number_info !== '') { info += ' (' + number_info + ')' }
852     if (name_info   !== '') { info += ' (' + name_info + ')' }
853
854     if (!$('#follow_up_rowcount').length) {
855       $('<input type="hidden" name="follow_up_rowcount"        id="follow_up_rowcount">').appendTo('#order_form');
856       $('<input type="hidden" name="follow_up_trans_id_1"      id="follow_up_trans_id_1">').appendTo('#order_form');
857       $('<input type="hidden" name="follow_up_trans_type_1"    id="follow_up_trans_type_1">').appendTo('#order_form');
858       $('<input type="hidden" name="follow_up_trans_info_1"    id="follow_up_trans_info_1">').appendTo('#order_form');
859       $('<input type="hidden" name="follow_up_trans_subject_1" id="follow_up_trans_subject_1">').appendTo('#order_form');
860     }
861     $('#follow_up_rowcount').val(1);
862     $('#follow_up_trans_id_1').val(id);
863     $('#follow_up_trans_type_1').val(type);
864     $('#follow_up_trans_info_1').val(info);
865     $('#follow_up_trans_subject_1').val($('#order_transaction_description').val());
866
867     follow_up_window();
868   };
869
870   ns.create_part = function() {
871     var data = $('#order_form').serializeArray();
872     data.push({ name: 'action', value: 'Order/create_part' });
873
874     $.post("controller.pl", data, kivi.eval_json_result);
875   };
876
877   ns.check_transport_cost_article_presence = function() {
878     var $form          = $('#order_form');
879     var wanted_part_id = $form.data('transport-cost-reminder-article-id');
880
881     if (!wanted_part_id) return true
882
883     var id_arr = $('[name="order.orderitems[].parts_id"]').map(function() { return this.value; }).get();
884     id_arr = $.grep(id_arr, function(elt) {
885       return ((elt*1) === wanted_part_id);
886     });
887
888     if (id_arr.length) return true;
889
890     var description = $form.data('transport-cost-reminder-article-description');
891     return confirm(kivi.t8("The transport cost article '#1' is missing. Do you want to continue anyway?", [ description ]));
892   };
893
894   ns.check_cusordnumber_presence = function() {
895     if ($('#order_cusordnumber').val() === '') {
896       return confirm(kivi.t8('The customer order number is missing. Do you want to continue anyway?'));
897     }
898     return true;
899   };
900
901 });
902
903 $(function() {
904   if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
905     $('#order_customer_id').change(kivi.Order.reload_cv_dependent_selections);
906   } else {
907     $('#order_vendor_id').change(kivi.Order.reload_cv_dependent_selections);
908   }
909
910   $('#order_currency_id').change(kivi.Order.update_exchangerate);
911   $('#order_transdate_as_date').change(kivi.Order.update_exchangerate);
912   $('#order_exchangerate_as_null_number').change(kivi.Order.exchangerate_changed);
913
914   $('#add_item_parts_id').on('set_item:PartPicker', function() {
915     kivi.Order.update_item_input_row();
916   });
917
918   $('.add_item_input').keydown(function(event) {
919     if (event.keyCode == 13) {
920       event.preventDefault();
921       kivi.Order.add_item();
922       return false;
923     }
924   });
925
926   kivi.Order.init_row_handlers();
927
928   $('#row_table_id').on('sortstop', function(event, ui) {
929     $('#row_table_id thead a img').remove();
930     kivi.Order.renumber_positions();
931   });
932
933   $('#expand_all').on('click', function(event) {
934     event.preventDefault();
935     if ($('#expand_all').data('expanded') == 1) {
936       $('#expand_all').data('expanded', 0);
937       $('#expand_all').attr('src', 'image/expand.svg');
938       $('#expand_all').attr('alt', kivi.t8('Show all details'));
939       $('#expand_all').attr('title', kivi.t8('Show all details'));
940       $('.row_entry').each(function(idx, elt) {
941         kivi.Order.hide_second_row(elt);
942       });
943     } else {
944       $('#expand_all').data('expanded', 1);
945       $('#expand_all').attr('src', "image/collapse.svg");
946       $('#expand_all').attr('alt', kivi.t8('Hide all details'));
947       $('#expand_all').attr('title', kivi.t8('Hide all details'));
948       kivi.Order.load_all_second_rows();
949       $('.row_entry').each(function(idx, elt) {
950         kivi.Order.show_second_row(elt);
951       });
952     }
953     return false;
954   });
955
956   $('.reformat_number_as_null_number').change(kivi.Order.reformat_number_as_null_number);
957
958 });