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