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.'));
9 if ($('#order_vendor_id').val() === '') {
10 alert(kivi.t8('Please select a vendor.'));
17 ns.check_save_duplicate_parts = function() {
18 var id_arr = $('[name="order.orderitems[].parts_id"]').map(function() {return this.value;}).get();
20 var i, obj = {}, pos = [];
22 for (i = 0; i < id_arr.length; i++) {
24 if (obj.hasOwnProperty(id)) {
31 return confirm(kivi.t8("There are duplicate parts at positions") + "\n"
32 + pos.join(', ') + "\n"
33 + kivi.t8("Do you really want to save?"));
38 ns.save = function(action, warn_on_duplicates) {
39 if (!ns.check_cv()) return;
40 if (warn_on_duplicates && !ns.check_save_duplicate_parts()) return;
42 var data = $('#order_form').serializeArray();
43 data.push({ name: 'action', value: 'Order/' + action });
45 $.post("controller.pl", data, kivi.eval_json_result);
48 ns.delete_order = function() {
49 var data = $('#order_form').serializeArray();
50 data.push({ name: 'action', value: 'Order/delete' });
52 $.post("controller.pl", data, kivi.eval_json_result);
55 ns.show_print_options = function() {
56 if (!ns.check_cv()) return;
61 title: kivi.t8('Print options'),
68 ns.print = function() {
69 $('#print_options').dialog('close');
71 var data = $('#order_form').serializeArray();
72 data = data.concat($('#print_options_form').serializeArray());
73 data.push({ name: 'action', value: 'Order/print' });
75 $.post("controller.pl", data, kivi.eval_json_result);
78 ns.download_pdf = function(pdf_filename, key) {
80 data.push({ name: 'action', value: 'Order/download_pdf' });
81 data.push({ name: 'type', value: $('#type').val() });
82 data.push({ name: 'pdf_filename', value: pdf_filename });
83 data.push({ name: 'key', value: key });
84 $.download("controller.pl", data);
87 ns.email = function() {
88 if (!ns.check_cv()) return;
89 var data = $('#order_form').serializeArray();
90 data.push({ name: 'action', value: 'Order/show_email_dialog' });
92 $.post("controller.pl", data, kivi.eval_json_result);
97 ns.setup_send_email_dialog = function() {
98 kivi.SalesPurchase.show_all_print_options_elements();
99 kivi.SalesPurchase.show_print_options_elements([ 'sendmode', 'media', 'copies', 'remove_draft' ], false);
101 $('#print_options_form table').first().remove().appendTo('#email_form_print_options');
103 var to_focus = $('#email_form_to').val() === '' ? 'to' : 'subject';
104 $('#email_form_' + to_focus).focus();
107 ns.finish_send_email_dialog = function() {
108 kivi.SalesPurchase.show_all_print_options_elements();
110 $('#email_form_print_options table').first().remove().prependTo('#print_options_form');
114 ns.show_email_dialog = function(html) {
115 var id = 'send_email_dialog';
116 var dialog_params = {
120 title: kivi.t8('Send email'),
122 beforeClose: kivi.Order.finish_send_email_dialog,
123 close: function(event, ui) {
124 email_dialog.remove();
128 $('#' + id).remove();
130 email_dialog = $('<div style="display:none" id="' + id + '"></div>').appendTo('body');
131 email_dialog.html(html);
132 email_dialog.dialog(dialog_params);
134 kivi.Order.setup_send_email_dialog();
136 $('.cancel').click(ns.close_email_dialog);
141 ns.send_email = function() {
142 var data = $('#order_form').serializeArray();
143 data = data.concat($('[name^="email_form."]').serializeArray());
144 data = data.concat($('[name^="print_options."]').serializeArray());
145 data.push({ name: 'action', value: 'Order/send_email' });
146 $.post("controller.pl", data, kivi.eval_json_result);
149 ns.close_email_dialog = function() {
150 email_dialog.dialog("close");
153 ns.set_number_in_title = function(elt) {
154 $('#nr_in_title').html($(elt).val());
157 ns.reload_cv_dependant_selections = function() {
158 var data = $('#order_form').serializeArray();
159 data.push({ name: 'action', value: 'Order/customer_vendor_changed' });
161 $.post("controller.pl", data, kivi.eval_json_result);
164 ns.reformat_number = function(event) {
165 $(event.target).val(kivi.format_amount(kivi.parse_amount($(event.target).val()), -2));
168 ns.recalc_amounts_and_taxes = function() {
169 var data = $('#order_form').serializeArray();
170 data.push({ name: 'action', value: 'Order/recalc_amounts_and_taxes' });
172 $.post("controller.pl", data, kivi.eval_json_result);
175 ns.unit_change = function(event) {
176 var row = $(event.target).parents("tbody").first();
177 var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
178 var sellprice_dom = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
179 var select_elt = $(row).find('[name="order.orderitems[].unit"]');
181 var oldval = $(select_elt).data('oldval');
182 $(select_elt).data('oldval', $(select_elt).val());
184 var data = $('#order_form').serializeArray();
185 data.push({ name: 'action', value: 'Order/unit_changed' });
186 data.push({ name: 'item_id', value: item_id_dom.val() });
187 data.push({ name: 'old_unit', value: oldval });
188 data.push({ name: 'sellprice_dom_id', value: sellprice_dom.attr('id') });
190 $.post("controller.pl", data, kivi.eval_json_result);
193 ns.update_sellprice = function(item_id, price_str) {
194 var row = $('#item_' + item_id).parents("tbody").first();
195 var price_elt = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
196 var html_elt = $(row).find('[name="sellprice_text"]');
197 price_elt.val(price_str);
198 html_elt.html(price_str);
201 ns.load_second_row = function(row) {
202 var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
203 var div_elt = $(row).find('[name="second_row"]');
205 if ($(div_elt).data('loaded') == 1) {
208 var data = $('#order_form').serializeArray();
209 data.push({ name: 'action', value: 'Order/load_second_rows' });
210 data.push({ name: 'item_ids[]', value: item_id_dom.val() });
212 $.post("controller.pl", data, kivi.eval_json_result);
215 ns.load_all_second_rows = function() {
216 var rows = $('.row_entry').filter(function(idx, elt) {
217 return $(elt).find('[name="second_row"]').data('loaded') != 1;
220 var item_ids = $.map(rows, function(elt) {
221 var item_id = $(elt).find('[name="orderitem_ids[+]"]').val();
222 return { name: 'item_ids[]', value: item_id };
225 if (item_ids.length == 0) {
229 var data = $('#order_form').serializeArray();
230 data.push({ name: 'action', value: 'Order/load_second_rows' });
231 data = data.concat(item_ids);
233 $.post("controller.pl", data, kivi.eval_json_result);
236 ns.hide_second_row = function(row) {
237 $(row).children().not(':first').hide();
238 $(row).data('expanded', 0);
239 var elt = $(row).find('.expand');
240 elt.attr('src', "image/expand.svg");
241 elt.attr('alt', kivi.t8('Show details'));
242 elt.attr('title', kivi.t8('Show details'));
245 ns.show_second_row = function(row) {
246 $(row).children().not(':first').show();
247 $(row).data('expanded', 1);
248 var elt = $(row).find('.expand');
249 elt.attr('src', "image/collapse.svg");
250 elt.attr('alt', kivi.t8('Hide details'));
251 elt.attr('title', kivi.t8('Hide details'));
254 ns.toggle_second_row = function(row) {
255 if ($(row).data('expanded') == 1) {
256 ns.hide_second_row(row);
258 ns.show_second_row(row);
262 ns.init_row_handlers = function() {
263 kivi.run_once_for('.recalc', 'on_change_recalc', function(elt) {
264 $(elt).change(ns.recalc_amounts_and_taxes);
267 kivi.run_once_for('.reformat_number', 'on_change_reformat', function(elt) {
268 $(elt).change(ns.reformat_number);
271 kivi.run_once_for('.unitselect', 'on_change_unit_with_oldval', function(elt) {
272 $(elt).data('oldval', $(elt).val());
273 $(elt).change(ns.unit_change);
276 kivi.run_once_for('.row_entry', 'on_kbd_click_show_hide', function(elt) {
277 $(elt).keydown(function(event) {
278 if(event.keyCode == 40 && event.shiftKey === true) {
280 event.preventDefault();
281 var row = $(event.target).parents(".row_entry").first();
282 ns.load_second_row(row);
283 ns.show_second_row(row);
286 if(event.keyCode == 38 && event.shiftKey === true) {
288 event.preventDefault();
289 var row = $(event.target).parents(".row_entry").first();
290 ns.hide_second_row(row);
296 kivi.run_once_for('.expand', 'expand_second_row', function(elt) {
297 $(elt).click(function(event) {
298 event.preventDefault();
299 var row = $(event.target).parents(".row_entry").first();
300 ns.load_second_row(row);
301 ns.toggle_second_row(row);
308 ns.redisplay_line_values = function(is_sales, data) {
309 $('.row_entry').each(function(idx, elt) {
310 $(elt).find('[name="linetotal"]').html(data[idx][0]);
311 if (is_sales && $(elt).find('[name="second_row"]').data('loaded') == 1) {
312 var mt = data[idx][1];
313 var mp = data[idx][2];
315 if (mt[0] === '-') h += ' class="plus0"';
316 h += '>' + mt + ' ' + mp + '%';
318 $(elt).find('[name="linemargin"]').html(h);
323 ns.renumber_positions = function() {
324 $('.row_entry [name="position"]').each(function(idx, elt) {
329 ns.reorder_items = function(order_by) {
330 var dir = $('#' + order_by + '_header_id a img').attr("data-sort-dir");
331 $('#row_table_id thead a img').remove();
336 src = "image/up.png";
339 src = "image/down.png";
342 $('#' + order_by + '_header_id a').append('<img border=0 data-sort-dir=' + dir + ' src=' + src + ' alt="' + kivi.t8('sort items') + '">');
344 var data = $('#order_form').serializeArray();
345 data.push({ name: 'action', value: 'Order/reorder_items' });
346 data.push({ name: 'order_by', value: order_by });
347 data.push({ name: 'sort_dir', value: dir });
349 $.post("controller.pl", data, kivi.eval_json_result);
352 ns.redisplay_items = function(data) {
353 var old_rows = $('.row_entry').detach();
355 $(data).each(function(idx, elt) {
356 new_rows.push(old_rows[elt.old_pos - 1]);
358 $(new_rows).appendTo($('#row_table_id'));
359 ns.renumber_positions();
362 ns.add_item = function() {
363 if ($('#add_item_parts_id').val() === '') return;
364 if (!ns.check_cv()) return;
366 $('#row_table_id thead a img').remove();
368 var data = $('#order_form').serializeArray();
369 data.push({ name: 'action', value: 'Order/add_item' });
371 $.post("controller.pl", data, kivi.eval_json_result);
374 ns.show_multi_items_dialog = function() {
375 if (!ns.check_cv()) return;
377 $('#row_table_id thead a img').remove();
380 url: 'controller.pl?action=Order/show_multi_items_dialog',
381 data: { type: $('#type').val(),
382 callback: 'Order/add_multi_items',
383 callback_data_id: 'order_form' },
384 id: 'jq_multi_items_dialog',
386 title: kivi.t8('Add multiple items'),
394 ns.close_multi_items_dialog = function() {
395 $('#jq_multi_items_dialog').dialog('close');
398 ns.delete_order_item_row = function(clicked) {
399 var row = $(clicked).parents("tbody").first();
402 ns.renumber_positions();
403 ns.recalc_amounts_and_taxes();
406 ns.row_table_scroll_down = function() {
407 $('#row_table_scroll_id').scrollTop($('#row_table_scroll_id')[0].scrollHeight);
410 ns.show_longdescription_dialog = function(clicked) {
411 var row = $(clicked).parents("tbody").first();
412 var position = $(row).find('[name="position"]').html();
413 var partnumber = $(row).find('[name="partnumber"]').html();
414 var description_elt = $(row).find('[name="order.orderitems[].description"]');
415 var description = description_elt.val();
416 var longdescription_elt = $(row).find('[name="order.orderitems[].longdescription"]');
419 if (!longdescription_elt.length) {
421 data.push({ name: 'action', value: 'Order/get_item_longdescription' });
422 data.push({ name: 'type', value: $('#type').val() });
423 data.push({ name: 'item_id', value: $(row).find('[name="order.orderitems[+].id"]').val() });
424 data.push({ name: 'parts_id', value: $(row).find('[name="order.orderitems[].parts_id"]').val() });
426 url: 'controller.pl',
431 success: function(val){
432 longdescription = val;
436 longdescription = longdescription_elt.val();
439 var params = { runningnumber: position,
440 partnumber: partnumber,
441 description: description,
442 default_longdescription: longdescription,
443 set_function: function(val){
444 longdescription_elt.remove();
445 $('<input type="hidden" name="order.orderitems[].longdescription">').insertAfter(description_elt).val(val);
449 kivi.SalesPurchase.edit_longdescription_with_params(params);
452 ns.price_chooser_item_row = function(clicked) {
453 if (!ns.check_cv()) return;
454 var row = $(clicked).parents("tbody").first();
455 var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
457 var data = $('#order_form').serializeArray();
458 data.push({ name: 'action', value: 'Order/price_popup' });
459 data.push({ name: 'item_id', value: item_id_dom.val() });
461 $.post("controller.pl", data, kivi.eval_json_result);
464 ns.update_price_source = function(item_id, source, descr, price_str, price_editable) {
465 var row = $('#item_' + item_id).parents("tbody").first();
466 var source_elt = $(row).find('[name="order.orderitems[].active_price_source"]');
467 var button_elt = $(row).find('[name="price_chooser_button"]');
469 button_elt.val(button_elt.val().replace(/.*\|/, descr + " |"));
470 source_elt.val(source);
472 var editable_div_elt = $(row).find('[name="editable_price"]');
473 var not_editable_div_elt = $(row).find('[name="not_editable_price"]');
474 if (price_editable == 1 && source === '') {
476 $(editable_div_elt).show();
477 $(not_editable_div_elt).hide();
478 $(editable_div_elt).find(':input').prop("disabled", false);
479 $(not_editable_div_elt).find(':input').prop("disabled", true);
482 $(editable_div_elt).hide();
483 $(not_editable_div_elt).show();
484 $(editable_div_elt).find(':input').prop("disabled", true);
485 $(not_editable_div_elt).find(':input').prop("disabled", false);
489 var price_elt = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
490 var html_elt = $(row).find('[name="sellprice_text"]');
491 price_elt.val(price_str);
492 html_elt.html(price_str);
493 ns.recalc_amounts_and_taxes();
496 kivi.io.close_dialog();
499 ns.update_discount_source = function(item_id, source, descr, discount_str, price_editable) {
500 var row = $('#item_' + item_id).parents("tbody").first();
501 var source_elt = $(row).find('[name="order.orderitems[].active_discount_source"]');
502 var button_elt = $(row).find('[name="price_chooser_button"]');
504 button_elt.val(button_elt.val().replace(/\|.*/, "| " + descr));
505 source_elt.val(source);
507 var editable_div_elt = $(row).find('[name="editable_discount"]');
508 var not_editable_div_elt = $(row).find('[name="not_editable_discount"]');
509 if (price_editable == 1 && source === '') {
511 $(editable_div_elt).show();
512 $(not_editable_div_elt).hide();
513 $(editable_div_elt).find(':input').prop("disabled", false);
514 $(not_editable_div_elt).find(':input').prop("disabled", true);
517 $(editable_div_elt).hide();
518 $(not_editable_div_elt).show();
519 $(editable_div_elt).find(':input').prop("disabled", true);
520 $(not_editable_div_elt).find(':input').prop("disabled", false);
524 var discount_elt = $(row).find('[name="order.orderitems[].discount_as_percent"]');
525 var html_elt = $(row).find('[name="discount_text"]');
526 discount_elt.val(discount_str);
527 html_elt.html(discount_str);
528 ns.recalc_amounts_and_taxes();
531 kivi.io.close_dialog();
534 ns.show_periodic_invoices_config_dialog = function() {
535 if ($('#type').val() !== 'sales_order') return;
538 url: 'controller.pl?action=Order/show_periodic_invoices_config_dialog',
539 data: { type : $('#type').val(),
541 config : $('#order_periodic_invoices_config').val(),
542 customer_id: $('#order_customer_id').val(),
543 transdate : $('#order_transdate').val(),
544 language_id: $('#language_id').val()
546 id: 'jq_periodic_invoices_config_dialog',
547 load: kivi.reinit_widgets,
549 title: kivi.t8('Edit the configuration for periodic invoices'),
557 ns.close_periodic_invoices_config_dialog = function() {
558 $('#jq_periodic_invoices_config_dialog').dialog('close');
561 ns.assign_periodic_invoices_config = function() {
562 var data = $('[name="Form"]').serializeArray();
563 data.push({ name: 'type', value: $('#type').val() });
564 data.push({ name: 'action', value: 'Order/assign_periodic_invoices_config' });
565 $.post("controller.pl", data, kivi.eval_json_result);
568 ns.check_save_active_periodic_invoices = function() {
569 var type = $('#type').val();
570 if (type !== 'sales_order') return true;
574 url: 'controller.pl',
575 data: { action: 'Order/get_has_active_periodic_invoices',
578 config: $('#order_periodic_invoices_config').val(),
583 success: function(val){
589 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?'));
595 ns.show_vc_details_dialog = function() {
596 if (!ns.check_cv()) return;
600 if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
602 vc_id = $('#order_customer_id').val();
603 title = kivi.t8('Customer details');
606 vc_id = $('#order_vendor_id').val();
607 title = kivi.t8('Vendor details');
611 url: 'controller.pl',
612 data: { action: 'Order/show_customer_vendor_details_dialog',
613 type : $('#type').val(),
617 id: 'jq_customer_vendor_details_dialog',
627 ns.show_calculate_qty_dialog = function(clicked) {
628 var row = $(clicked).parents("tbody").first();
629 var input_id = $(row).find('[name="order.orderitems[].qty_as_number"]').attr('id');
630 var formula_id = $(row).find('[name="formula[+]"]').attr('id');
632 calculate_qty_selection_dialog("", input_id, "", formula_id);
639 if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
640 $('#order_customer_id').change(kivi.Order.reload_cv_dependant_selections);
642 $('#order_vendor_id').change(kivi.Order.reload_cv_dependant_selections);
645 if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
646 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_sellprice_as_number').val(kivi.format_amount(o.sellprice, -2)) });
648 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_sellprice_as_number').val(kivi.format_amount(o.lastcost, -2)) });
650 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_description').val(o.description) });
651 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_unit').val(o.unit) });
653 $('.add_item_input').keydown(function(event) {
654 if(event.keyCode == 13) {
655 event.preventDefault();
656 kivi.Order.add_item();
661 kivi.Order.init_row_handlers();
663 $('#row_table_id').on('sortstop', function(event, ui) {
664 $('#row_table_id thead a img').remove();
665 kivi.Order.renumber_positions();
668 $('#expand_all').on('click', function(event) {
669 event.preventDefault();
670 if ($('#expand_all').data('expanded') == 1) {
671 $('#expand_all').data('expanded', 0);
672 $('#expand_all').attr('src', 'image/expand.svg');
673 $('#expand_all').attr('alt', kivi.t8('Show all details'));
674 $('#expand_all').attr('title', kivi.t8('Show all details'));
675 $('.row_entry').each(function(idx, elt) {
676 kivi.Order.hide_second_row(elt);
679 $('#expand_all').data('expanded', 1);
680 $('#expand_all').attr('src', "image/collapse.svg");
681 $('#expand_all').attr('alt', kivi.t8('Hide all details'));
682 $('#expand_all').attr('title', kivi.t8('Hide all details'));
683 kivi.Order.load_all_second_rows();
684 $('.row_entry').each(function(idx, elt) {
685 kivi.Order.show_second_row(elt);