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