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