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