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