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