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