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