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