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