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_duplicate_parts = function(question) {
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 question = question || kivi.t8("Do you really want to save?");
32 return confirm(kivi.t8("There are duplicate parts at positions") + "\n"
33 + pos.join(', ') + "\n"
39 ns.check_valid_reqdate = function() {
40 if ($('#order_reqdate_as_date').val() === '') {
41 alert(kivi.t8('Please select a delivery date.'));
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;
53 var data = $('#order_form').serializeArray();
54 data.push({ name: 'action', value: 'Order/' + action });
56 $.post("controller.pl", data, kivi.eval_json_result);
59 ns.delete_order = function() {
60 var data = $('#order_form').serializeArray();
61 data.push({ name: 'action', value: 'Order/delete' });
63 $.post("controller.pl", data, kivi.eval_json_result);
66 ns.show_print_options = function(warn_on_duplicates) {
67 if (!ns.check_cv()) return;
68 if (warn_on_duplicates && !ns.check_duplicate_parts(kivi.t8("Do you really want to print?"))) return;
73 title: kivi.t8('Print options'),
80 ns.print = function() {
81 $('#print_options').dialog('close');
83 var data = $('#order_form').serializeArray();
84 data = data.concat($('#print_options_form').serializeArray());
85 data.push({ name: 'action', value: 'Order/print' });
87 $.post("controller.pl", data, kivi.eval_json_result);
90 ns.download_pdf = function(pdf_filename, key) {
91 var data = [{ name: 'action', value: 'Order/download_pdf' },
92 { name: 'type', value: $('#type').val() },
93 { name: 'pdf_filename', value: pdf_filename },
94 { name: 'key', value: key }];
95 $.download("controller.pl", data);
98 ns.email = function(warn_on_duplicates) {
99 if (warn_on_duplicates && !ns.check_duplicate_parts(kivi.t8("Do you really want to send by mail?"))) return;
100 if (!ns.check_cv()) return;
102 var data = $('#order_form').serializeArray();
103 data.push({ name: 'action', value: 'Order/show_email_dialog' });
105 $.post("controller.pl", data, kivi.eval_json_result);
110 ns.setup_send_email_dialog = function() {
111 kivi.SalesPurchase.show_all_print_options_elements();
112 kivi.SalesPurchase.show_print_options_elements([ 'sendmode', 'media', 'copies', 'remove_draft' ], false);
114 $('#print_options_form table').first().remove().appendTo('#email_form_print_options');
116 var to_focus = $('#email_form_to').val() === '' ? 'to' : 'subject';
117 $('#email_form_' + to_focus).focus();
120 ns.finish_send_email_dialog = function() {
121 kivi.SalesPurchase.show_all_print_options_elements();
123 $('#email_form_print_options table').first().remove().prependTo('#print_options_form');
127 ns.show_email_dialog = function(html) {
128 var id = 'send_email_dialog';
129 var dialog_params = {
133 title: kivi.t8('Send email'),
135 beforeClose: kivi.Order.finish_send_email_dialog,
136 close: function(event, ui) {
137 email_dialog.remove();
141 $('#' + id).remove();
143 email_dialog = $('<div style="display:none" id="' + id + '"></div>').appendTo('body');
144 email_dialog.html(html);
145 email_dialog.dialog(dialog_params);
147 kivi.Order.setup_send_email_dialog();
149 $('.cancel').click(ns.close_email_dialog);
154 ns.send_email = function() {
155 var data = $('#order_form').serializeArray();
156 data = data.concat($('[name^="email_form."]').serializeArray());
157 data = data.concat($('[name^="print_options."]').serializeArray());
158 data.push({ name: 'action', value: 'Order/send_email' });
159 $.post("controller.pl", data, kivi.eval_json_result);
162 ns.close_email_dialog = function() {
163 email_dialog.dialog("close");
166 ns.set_number_in_title = function(elt) {
167 $('#nr_in_title').html($(elt).val());
170 ns.reload_cv_dependant_selections = function() {
171 var data = $('#order_form').serializeArray();
172 data.push({ name: 'action', value: 'Order/customer_vendor_changed' });
174 $.post("controller.pl", data, kivi.eval_json_result);
177 ns.reformat_number = function(event) {
178 $(event.target).val(kivi.format_amount(kivi.parse_amount($(event.target).val()), -2));
181 ns.recalc_amounts_and_taxes = function() {
182 var data = $('#order_form').serializeArray();
183 data.push({ name: 'action', value: 'Order/recalc_amounts_and_taxes' });
185 $.post("controller.pl", data, kivi.eval_json_result);
188 ns.unit_change = function(event) {
189 var row = $(event.target).parents("tbody").first();
190 var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
191 var sellprice_dom = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
192 var select_elt = $(row).find('[name="order.orderitems[].unit"]');
194 var oldval = $(select_elt).data('oldval');
195 $(select_elt).data('oldval', $(select_elt).val());
197 var data = $('#order_form').serializeArray();
198 data.push({ name: 'action', value: 'Order/unit_changed' },
199 { name: 'item_id', value: item_id_dom.val() },
200 { name: 'old_unit', value: oldval },
201 { name: 'sellprice_dom_id', value: sellprice_dom.attr('id') });
203 $.post("controller.pl", data, kivi.eval_json_result);
206 ns.update_sellprice = function(item_id, price_str) {
207 var row = $('#item_' + item_id).parents("tbody").first();
208 var price_elt = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
209 var html_elt = $(row).find('[name="sellprice_text"]');
210 price_elt.val(price_str);
211 html_elt.html(price_str);
214 ns.load_second_row = function(row) {
215 var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
216 var div_elt = $(row).find('[name="second_row"]');
218 if ($(div_elt).data('loaded') == 1) {
221 var data = $('#order_form').serializeArray();
222 data.push({ name: 'action', value: 'Order/load_second_rows' },
223 { name: 'item_ids[]', value: item_id_dom.val() });
225 $.post("controller.pl", data, kivi.eval_json_result);
228 ns.load_all_second_rows = function() {
229 var rows = $('.row_entry').filter(function(idx, elt) {
230 return $(elt).find('[name="second_row"]').data('loaded') != 1;
233 var item_ids = $.map(rows, function(elt) {
234 var item_id = $(elt).find('[name="orderitem_ids[+]"]').val();
235 return { name: 'item_ids[]', value: item_id };
238 if (item_ids.length == 0) {
242 var data = $('#order_form').serializeArray();
243 data.push({ name: 'action', value: 'Order/load_second_rows' });
244 data = data.concat(item_ids);
246 $.post("controller.pl", data, kivi.eval_json_result);
249 ns.hide_second_row = function(row) {
250 $(row).children().not(':first').hide();
251 $(row).data('expanded', 0);
252 var elt = $(row).find('.expand');
253 elt.attr('src', "image/expand.svg");
254 elt.attr('alt', kivi.t8('Show details'));
255 elt.attr('title', kivi.t8('Show details'));
258 ns.show_second_row = function(row) {
259 $(row).children().not(':first').show();
260 $(row).data('expanded', 1);
261 var elt = $(row).find('.expand');
262 elt.attr('src', "image/collapse.svg");
263 elt.attr('alt', kivi.t8('Hide details'));
264 elt.attr('title', kivi.t8('Hide details'));
267 ns.toggle_second_row = function(row) {
268 if ($(row).data('expanded') == 1) {
269 ns.hide_second_row(row);
271 ns.show_second_row(row);
275 ns.init_row_handlers = function() {
276 kivi.run_once_for('.recalc', 'on_change_recalc', function(elt) {
277 $(elt).change(ns.recalc_amounts_and_taxes);
280 kivi.run_once_for('.reformat_number', 'on_change_reformat', function(elt) {
281 $(elt).change(ns.reformat_number);
284 kivi.run_once_for('.unitselect', 'on_change_unit_with_oldval', function(elt) {
285 $(elt).data('oldval', $(elt).val());
286 $(elt).change(ns.unit_change);
289 kivi.run_once_for('.row_entry', 'on_kbd_click_show_hide', function(elt) {
290 $(elt).keydown(function(event) {
292 if (event.keyCode == 40 && event.shiftKey === true) {
294 event.preventDefault();
295 row = $(event.target).parents(".row_entry").first();
296 ns.load_second_row(row);
297 ns.show_second_row(row);
300 if (event.keyCode == 38 && event.shiftKey === true) {
302 event.preventDefault();
303 row = $(event.target).parents(".row_entry").first();
304 ns.hide_second_row(row);
310 kivi.run_once_for('.expand', 'expand_second_row', function(elt) {
311 $(elt).click(function(event) {
312 event.preventDefault();
313 var row = $(event.target).parents(".row_entry").first();
314 ns.load_second_row(row);
315 ns.toggle_second_row(row);
322 ns.redisplay_line_values = function(is_sales, data) {
323 $('.row_entry').each(function(idx, elt) {
324 $(elt).find('[name="linetotal"]').html(data[idx][0]);
325 if (is_sales && $(elt).find('[name="second_row"]').data('loaded') == 1) {
326 var mt = data[idx][1];
327 var mp = data[idx][2];
329 if (mt[0] === '-') h += ' class="plus0"';
330 h += '>' + mt + ' ' + mp + '%';
332 $(elt).find('[name="linemargin"]').html(h);
337 ns.renumber_positions = function() {
338 $('.row_entry [name="position"]').each(function(idx, elt) {
343 ns.reorder_items = function(order_by) {
344 var dir = $('#' + order_by + '_header_id a img').attr("data-sort-dir");
345 $('#row_table_id thead a img').remove();
350 src = "image/up.png";
353 src = "image/down.png";
356 $('#' + order_by + '_header_id a').append('<img border=0 data-sort-dir=' + dir + ' src=' + src + ' alt="' + kivi.t8('sort items') + '">');
358 var data = $('#order_form').serializeArray();
359 data.push({ name: 'action', value: 'Order/reorder_items' },
360 { name: 'order_by', value: order_by },
361 { name: 'sort_dir', value: dir });
363 $.post("controller.pl", data, kivi.eval_json_result);
366 ns.redisplay_items = function(data) {
367 var old_rows = $('.row_entry').detach();
369 $(data).each(function(idx, elt) {
370 new_rows.push(old_rows[elt.old_pos - 1]);
372 $(new_rows).appendTo($('#row_table_id'));
373 ns.renumber_positions();
376 ns.add_item = function() {
377 if ($('#add_item_parts_id').val() === '') return;
378 if (!ns.check_cv()) return;
380 $('#row_table_id thead a img').remove();
382 var data = $('#order_form').serializeArray();
383 data.push({ name: 'action', value: 'Order/add_item' });
385 $.post("controller.pl", data, kivi.eval_json_result);
388 ns.setup_multi_items_dialog = function() {
389 $('#multi_items_filter_table input, #multi_items_filter_table select').keydown(function(event) {
390 if (event.keyCode == 13) {
391 event.preventDefault();
392 ns.multi_items_dialog_update_result();
397 $('#multi_items_filter_all_substr_multi_ilike').focus();
400 ns.show_multi_items_dialog = function() {
401 if (!ns.check_cv()) return;
403 $('#row_table_id thead a img').remove();
406 url: 'controller.pl?action=Order/show_multi_items_dialog',
407 data: { type: $('#type').val() },
408 id: 'jq_multi_items_dialog',
409 load: kivi.Order.setup_multi_items_dialog,
411 title: kivi.t8('Add multiple items'),
419 ns.close_multi_items_dialog = function() {
420 $('#jq_multi_items_dialog').dialog('close');
423 ns.multi_items_dialog_update_result = function() {
424 var data = $('#multi_items_form').serializeArray();
425 data.push({ name: 'type', value: $('#type').val() });
427 url: 'controller.pl?action=Order/multi_items_update_result',
430 success: function(data) {
431 $('#multi_items_result').html(data);
432 ns.multi_items_dialog_enable_continue();
433 ns.multi_items_result_setup_events();
438 ns.multi_items_dialog_disable_continue = function() {
439 // disable keydown-event and continue button to prevent
440 // impatient users to add parts multiple times
441 $('#multi_items_result input').off("keydown");
442 $('#multi_items_dialog_continue_button').prop('disabled', true);
445 ns.multi_items_dialog_enable_continue = function() {
446 $('#multi_items_result input').keydown(function(event) {
447 if(event.keyCode == 13) {
448 event.preventDefault();
449 ns.add_multi_items();
453 $('#multi_items_dialog_continue_button').prop('disabled', false);
456 ns.multi_items_result_setup_events = function() {
457 $('#multi_items_all_qty').change(ns.reformat_number);
458 $('#multi_items_all_qty').change(function(event) {
459 $('.multi_items_qty').val($(event.target).val());
461 $('.multi_items_qty').change(ns.reformat_number);
464 ns.add_multi_items = function() {
466 var n_rows = $('.multi_items_qty').length;
467 if (n_rows == 0) return;
470 n_rows = $('.multi_items_qty').filter(function() {
471 return $(this).val().length > 0;
473 if (n_rows == 0) return;
475 ns.multi_items_dialog_disable_continue();
477 var data = $('#order_form').serializeArray();
478 data = data.concat($('#multi_items_form').serializeArray());
479 data.push({ name: 'action', value: 'Order/add_multi_items' });
480 $.post("controller.pl", data, kivi.eval_json_result);
483 ns.set_input_to_one = function(clicked) {
484 if ($(clicked).val() == '') {
485 $(clicked).val(kivi.format_amount(1.00, -2));
490 ns.delete_order_item_row = function(clicked) {
491 var row = $(clicked).parents("tbody").first();
494 ns.renumber_positions();
495 ns.recalc_amounts_and_taxes();
498 ns.row_table_scroll_down = function() {
499 $('#row_table_scroll_id').scrollTop($('#row_table_scroll_id')[0].scrollHeight);
502 ns.show_longdescription_dialog = function(clicked) {
503 var row = $(clicked).parents("tbody").first();
504 var position = $(row).find('[name="position"]').html();
505 var partnumber = $(row).find('[name="partnumber"]').html();
506 var description_elt = $(row).find('[name="order.orderitems[].description"]');
507 var description = description_elt.val();
508 var longdescription_elt = $(row).find('[name="order.orderitems[].longdescription"]');
511 if (!longdescription_elt.length) {
513 { name: 'action', value: 'Order/get_item_longdescription' },
514 { name: 'type', value: $('#type').val() },
515 { name: 'item_id', value: $(row).find('[name="order.orderitems[+].id"]').val() },
516 { name: 'parts_id', value: $(row).find('[name="order.orderitems[].parts_id"]').val() }
520 url: 'controller.pl',
525 success: function(val) {
526 longdescription = val;
530 longdescription = longdescription_elt.val();
534 runningnumber: position,
535 partnumber: partnumber,
536 description: description,
537 default_longdescription: longdescription,
538 set_function: function(val) {
539 longdescription_elt.remove();
540 $('<input type="hidden" name="order.orderitems[].longdescription">').insertAfter(description_elt).val(val);
544 kivi.SalesPurchase.edit_longdescription_with_params(params);
547 ns.price_chooser_item_row = function(clicked) {
548 if (!ns.check_cv()) return;
549 var row = $(clicked).parents("tbody").first();
550 var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
552 var data = $('#order_form').serializeArray();
553 data.push({ name: 'action', value: 'Order/price_popup' },
554 { name: 'item_id', value: item_id_dom.val() });
556 $.post("controller.pl", data, kivi.eval_json_result);
559 ns.update_price_source = function(item_id, source, descr, price_str, price_editable) {
560 var row = $('#item_' + item_id).parents("tbody").first();
561 var source_elt = $(row).find('[name="order.orderitems[].active_price_source"]');
562 var button_elt = $(row).find('[name="price_chooser_button"]');
564 button_elt.val(button_elt.val().replace(/.*\|/, descr + " |"));
565 source_elt.val(source);
567 var editable_div_elt = $(row).find('[name="editable_price"]');
568 var not_editable_div_elt = $(row).find('[name="not_editable_price"]');
569 if (price_editable == 1 && source === '') {
571 $(editable_div_elt).show();
572 $(not_editable_div_elt).hide();
573 $(editable_div_elt).find(':input').prop("disabled", false);
574 $(not_editable_div_elt).find(':input').prop("disabled", true);
577 $(editable_div_elt).hide();
578 $(not_editable_div_elt).show();
579 $(editable_div_elt).find(':input').prop("disabled", true);
580 $(not_editable_div_elt).find(':input').prop("disabled", false);
584 var price_elt = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
585 var html_elt = $(row).find('[name="sellprice_text"]');
586 price_elt.val(price_str);
587 html_elt.html(price_str);
588 ns.recalc_amounts_and_taxes();
591 kivi.io.close_dialog();
594 ns.update_discount_source = function(item_id, source, descr, discount_str, price_editable) {
595 var row = $('#item_' + item_id).parents("tbody").first();
596 var source_elt = $(row).find('[name="order.orderitems[].active_discount_source"]');
597 var button_elt = $(row).find('[name="price_chooser_button"]');
599 button_elt.val(button_elt.val().replace(/\|.*/, "| " + descr));
600 source_elt.val(source);
602 var editable_div_elt = $(row).find('[name="editable_discount"]');
603 var not_editable_div_elt = $(row).find('[name="not_editable_discount"]');
604 if (price_editable == 1 && source === '') {
606 $(editable_div_elt).show();
607 $(not_editable_div_elt).hide();
608 $(editable_div_elt).find(':input').prop("disabled", false);
609 $(not_editable_div_elt).find(':input').prop("disabled", true);
612 $(editable_div_elt).hide();
613 $(not_editable_div_elt).show();
614 $(editable_div_elt).find(':input').prop("disabled", true);
615 $(not_editable_div_elt).find(':input').prop("disabled", false);
619 var discount_elt = $(row).find('[name="order.orderitems[].discount_as_percent"]');
620 var html_elt = $(row).find('[name="discount_text"]');
621 discount_elt.val(discount_str);
622 html_elt.html(discount_str);
623 ns.recalc_amounts_and_taxes();
626 kivi.io.close_dialog();
629 ns.show_periodic_invoices_config_dialog = function() {
630 if ($('#type').val() !== 'sales_order') return;
633 url: 'controller.pl?action=Order/show_periodic_invoices_config_dialog',
634 data: { type: $('#type').val(),
636 config: $('#order_periodic_invoices_config').val(),
637 customer_id: $('#order_customer_id').val(),
638 transdate_as_date: $('#order_transdate_as_date').val(),
639 language_id: $('#language_id').val()
641 id: 'jq_periodic_invoices_config_dialog',
642 load: kivi.reinit_widgets,
644 title: kivi.t8('Edit the configuration for periodic invoices'),
652 ns.close_periodic_invoices_config_dialog = function() {
653 $('#jq_periodic_invoices_config_dialog').dialog('close');
656 ns.assign_periodic_invoices_config = function() {
657 var data = $('[name="Form"]').serializeArray();
658 data.push({ name: 'type', value: $('#type').val() },
659 { name: 'action', value: 'Order/assign_periodic_invoices_config' });
660 $.post("controller.pl", data, kivi.eval_json_result);
663 ns.check_save_active_periodic_invoices = function() {
664 var type = $('#type').val();
665 if (type !== 'sales_order') return true;
669 url: 'controller.pl',
670 data: { action: 'Order/get_has_active_periodic_invoices',
673 config: $('#order_periodic_invoices_config').val(),
678 success: function(val) {
684 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?'));
690 ns.show_vc_details_dialog = function() {
691 if (!ns.check_cv()) return;
695 if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
697 vc_id = $('#order_customer_id').val();
698 title = kivi.t8('Customer details');
701 vc_id = $('#order_vendor_id').val();
702 title = kivi.t8('Vendor details');
706 url: 'controller.pl',
707 data: { action: 'Order/show_customer_vendor_details_dialog',
708 type : $('#type').val(),
712 id: 'jq_customer_vendor_details_dialog',
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');
727 calculate_qty_selection_dialog("", input_id, "", formula_id);
734 if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
735 $('#order_customer_id').change(kivi.Order.reload_cv_dependant_selections);
737 $('#order_vendor_id').change(kivi.Order.reload_cv_dependant_selections);
740 if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
741 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_sellprice_as_number').val(kivi.format_amount(o.sellprice, -2)) });
743 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_sellprice_as_number').val(kivi.format_amount(o.lastcost, -2)) });
745 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_description').val(o.description) });
746 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_unit').val(o.unit) });
748 $('.add_item_input').keydown(function(event) {
749 if (event.keyCode == 13) {
750 event.preventDefault();
751 kivi.Order.add_item();
756 kivi.Order.init_row_handlers();
758 $('#row_table_id').on('sortstop', function(event, ui) {
759 $('#row_table_id thead a img').remove();
760 kivi.Order.renumber_positions();
763 $('#expand_all').on('click', function(event) {
764 event.preventDefault();
765 if ($('#expand_all').data('expanded') == 1) {
766 $('#expand_all').data('expanded', 0);
767 $('#expand_all').attr('src', 'image/expand.svg');
768 $('#expand_all').attr('alt', kivi.t8('Show all details'));
769 $('#expand_all').attr('title', kivi.t8('Show all details'));
770 $('.row_entry').each(function(idx, elt) {
771 kivi.Order.hide_second_row(elt);
774 $('#expand_all').data('expanded', 1);
775 $('#expand_all').attr('src', "image/collapse.svg");
776 $('#expand_all').attr('alt', kivi.t8('Hide all details'));
777 $('#expand_all').attr('title', kivi.t8('Hide all details'));
778 kivi.Order.load_all_second_rows();
779 $('.row_entry').each(function(idx, elt) {
780 kivi.Order.show_second_row(elt);