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.check_valid_reqdate = function() {
39 if ($('#order_reqdate').val() === '') {
40 alert(kivi.t8('Please select a delivery date.'));
47 ns.save = function(action, warn_on_duplicates, warn_on_reqdate) {
48 if (!ns.check_cv()) return;
49 if (warn_on_duplicates && !ns.check_save_duplicate_parts()) return;
50 if (warn_on_reqdate && !ns.check_valid_reqdate()) return;
52 var data = $('#order_form').serializeArray();
53 data.push({ name: 'action', value: 'Order/' + action });
55 $.post("controller.pl", data, kivi.eval_json_result);
58 ns.delete_order = function() {
59 var data = $('#order_form').serializeArray();
60 data.push({ name: 'action', value: 'Order/delete' });
62 $.post("controller.pl", data, kivi.eval_json_result);
65 ns.show_print_options = function() {
66 if (!ns.check_cv()) return;
71 title: kivi.t8('Print options'),
78 ns.print = function() {
79 $('#print_options').dialog('close');
81 var data = $('#order_form').serializeArray();
82 data = data.concat($('#print_options_form').serializeArray());
83 data.push({ name: 'action', value: 'Order/print' });
85 $.post("controller.pl", data, kivi.eval_json_result);
88 ns.download_pdf = function(pdf_filename, key) {
89 var data = [{ name: 'action', value: 'Order/download_pdf' },
90 { name: 'type', value: $('#type').val() },
91 { name: 'pdf_filename', value: pdf_filename },
92 { name: 'key', value: key }];
93 $.download("controller.pl", data);
96 ns.email = function() {
97 if (!ns.check_cv()) return;
98 var data = $('#order_form').serializeArray();
99 data.push({ name: 'action', value: 'Order/show_email_dialog' });
101 $.post("controller.pl", data, kivi.eval_json_result);
106 ns.setup_send_email_dialog = function() {
107 kivi.SalesPurchase.show_all_print_options_elements();
108 kivi.SalesPurchase.show_print_options_elements([ 'sendmode', 'media', 'copies', 'remove_draft' ], false);
110 $('#print_options_form table').first().remove().appendTo('#email_form_print_options');
112 var to_focus = $('#email_form_to').val() === '' ? 'to' : 'subject';
113 $('#email_form_' + to_focus).focus();
116 ns.finish_send_email_dialog = function() {
117 kivi.SalesPurchase.show_all_print_options_elements();
119 $('#email_form_print_options table').first().remove().prependTo('#print_options_form');
123 ns.show_email_dialog = function(html) {
124 var id = 'send_email_dialog';
125 var dialog_params = {
129 title: kivi.t8('Send email'),
131 beforeClose: kivi.Order.finish_send_email_dialog,
132 close: function(event, ui) {
133 email_dialog.remove();
137 $('#' + id).remove();
139 email_dialog = $('<div style="display:none" id="' + id + '"></div>').appendTo('body');
140 email_dialog.html(html);
141 email_dialog.dialog(dialog_params);
143 kivi.Order.setup_send_email_dialog();
145 $('.cancel').click(ns.close_email_dialog);
150 ns.send_email = function() {
151 var data = $('#order_form').serializeArray();
152 data = data.concat($('[name^="email_form."]').serializeArray());
153 data = data.concat($('[name^="print_options."]').serializeArray());
154 data.push({ name: 'action', value: 'Order/send_email' });
155 $.post("controller.pl", data, kivi.eval_json_result);
158 ns.close_email_dialog = function() {
159 email_dialog.dialog("close");
162 ns.set_number_in_title = function(elt) {
163 $('#nr_in_title').html($(elt).val());
166 ns.reload_cv_dependant_selections = function() {
167 var data = $('#order_form').serializeArray();
168 data.push({ name: 'action', value: 'Order/customer_vendor_changed' });
170 $.post("controller.pl", data, kivi.eval_json_result);
173 ns.reformat_number = function(event) {
174 $(event.target).val(kivi.format_amount(kivi.parse_amount($(event.target).val()), -2));
177 ns.recalc_amounts_and_taxes = function() {
178 var data = $('#order_form').serializeArray();
179 data.push({ name: 'action', value: 'Order/recalc_amounts_and_taxes' });
181 $.post("controller.pl", data, kivi.eval_json_result);
184 ns.unit_change = function(event) {
185 var row = $(event.target).parents("tbody").first();
186 var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
187 var sellprice_dom = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
188 var select_elt = $(row).find('[name="order.orderitems[].unit"]');
190 var oldval = $(select_elt).data('oldval');
191 $(select_elt).data('oldval', $(select_elt).val());
193 var data = $('#order_form').serializeArray();
194 data.push({ name: 'action', value: 'Order/unit_changed' },
195 { name: 'item_id', value: item_id_dom.val() },
196 { name: 'old_unit', value: oldval },
197 { name: 'sellprice_dom_id', value: sellprice_dom.attr('id') });
199 $.post("controller.pl", data, kivi.eval_json_result);
202 ns.update_sellprice = function(item_id, price_str) {
203 var row = $('#item_' + item_id).parents("tbody").first();
204 var price_elt = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
205 var html_elt = $(row).find('[name="sellprice_text"]');
206 price_elt.val(price_str);
207 html_elt.html(price_str);
210 ns.load_second_row = function(row) {
211 var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
212 var div_elt = $(row).find('[name="second_row"]');
214 if ($(div_elt).data('loaded') == 1) {
217 var data = $('#order_form').serializeArray();
218 data.push({ name: 'action', value: 'Order/load_second_rows' },
219 { name: 'item_ids[]', value: item_id_dom.val() });
221 $.post("controller.pl", data, kivi.eval_json_result);
224 ns.load_all_second_rows = function() {
225 var rows = $('.row_entry').filter(function(idx, elt) {
226 return $(elt).find('[name="second_row"]').data('loaded') != 1;
229 var item_ids = $.map(rows, function(elt) {
230 var item_id = $(elt).find('[name="orderitem_ids[+]"]').val();
231 return { name: 'item_ids[]', value: item_id };
234 if (item_ids.length == 0) {
238 var data = $('#order_form').serializeArray();
239 data.push({ name: 'action', value: 'Order/load_second_rows' });
240 data = data.concat(item_ids);
242 $.post("controller.pl", data, kivi.eval_json_result);
245 ns.hide_second_row = function(row) {
246 $(row).children().not(':first').hide();
247 $(row).data('expanded', 0);
248 var elt = $(row).find('.expand');
249 elt.attr('src', "image/expand.svg");
250 elt.attr('alt', kivi.t8('Show details'));
251 elt.attr('title', kivi.t8('Show details'));
254 ns.show_second_row = function(row) {
255 $(row).children().not(':first').show();
256 $(row).data('expanded', 1);
257 var elt = $(row).find('.expand');
258 elt.attr('src', "image/collapse.svg");
259 elt.attr('alt', kivi.t8('Hide details'));
260 elt.attr('title', kivi.t8('Hide details'));
263 ns.toggle_second_row = function(row) {
264 if ($(row).data('expanded') == 1) {
265 ns.hide_second_row(row);
267 ns.show_second_row(row);
271 ns.init_row_handlers = function() {
272 kivi.run_once_for('.recalc', 'on_change_recalc', function(elt) {
273 $(elt).change(ns.recalc_amounts_and_taxes);
276 kivi.run_once_for('.reformat_number', 'on_change_reformat', function(elt) {
277 $(elt).change(ns.reformat_number);
280 kivi.run_once_for('.unitselect', 'on_change_unit_with_oldval', function(elt) {
281 $(elt).data('oldval', $(elt).val());
282 $(elt).change(ns.unit_change);
285 kivi.run_once_for('.row_entry', 'on_kbd_click_show_hide', function(elt) {
286 $(elt).keydown(function(event) {
288 if (event.keyCode == 40 && event.shiftKey === true) {
290 event.preventDefault();
291 row = $(event.target).parents(".row_entry").first();
292 ns.load_second_row(row);
293 ns.show_second_row(row);
296 if (event.keyCode == 38 && event.shiftKey === true) {
298 event.preventDefault();
299 row = $(event.target).parents(".row_entry").first();
300 ns.hide_second_row(row);
306 kivi.run_once_for('.expand', 'expand_second_row', function(elt) {
307 $(elt).click(function(event) {
308 event.preventDefault();
309 var row = $(event.target).parents(".row_entry").first();
310 ns.load_second_row(row);
311 ns.toggle_second_row(row);
318 ns.redisplay_line_values = function(is_sales, data) {
319 $('.row_entry').each(function(idx, elt) {
320 $(elt).find('[name="linetotal"]').html(data[idx][0]);
321 if (is_sales && $(elt).find('[name="second_row"]').data('loaded') == 1) {
322 var mt = data[idx][1];
323 var mp = data[idx][2];
325 if (mt[0] === '-') h += ' class="plus0"';
326 h += '>' + mt + ' ' + mp + '%';
328 $(elt).find('[name="linemargin"]').html(h);
333 ns.renumber_positions = function() {
334 $('.row_entry [name="position"]').each(function(idx, elt) {
339 ns.reorder_items = function(order_by) {
340 var dir = $('#' + order_by + '_header_id a img').attr("data-sort-dir");
341 $('#row_table_id thead a img').remove();
346 src = "image/up.png";
349 src = "image/down.png";
352 $('#' + order_by + '_header_id a').append('<img border=0 data-sort-dir=' + dir + ' src=' + src + ' alt="' + kivi.t8('sort items') + '">');
354 var data = $('#order_form').serializeArray();
355 data.push({ name: 'action', value: 'Order/reorder_items' },
356 { name: 'order_by', value: order_by },
357 { name: 'sort_dir', value: dir });
359 $.post("controller.pl", data, kivi.eval_json_result);
362 ns.redisplay_items = function(data) {
363 var old_rows = $('.row_entry').detach();
365 $(data).each(function(idx, elt) {
366 new_rows.push(old_rows[elt.old_pos - 1]);
368 $(new_rows).appendTo($('#row_table_id'));
369 ns.renumber_positions();
372 ns.add_item = function() {
373 if ($('#add_item_parts_id').val() === '') return;
374 if (!ns.check_cv()) return;
376 $('#row_table_id thead a img').remove();
378 var data = $('#order_form').serializeArray();
379 data.push({ name: 'action', value: 'Order/add_item' });
381 $.post("controller.pl", data, kivi.eval_json_result);
384 ns.show_multi_items_dialog = function() {
385 if (!ns.check_cv()) return;
387 $('#row_table_id thead a img').remove();
390 url: 'controller.pl?action=Order/show_multi_items_dialog',
391 data: { type: $('#type').val(),
392 callback: 'Order/add_multi_items',
393 callback_data_id: 'order_form' },
394 id: 'jq_multi_items_dialog',
396 title: kivi.t8('Add multiple items'),
404 ns.close_multi_items_dialog = function() {
405 $('#jq_multi_items_dialog').dialog('close');
408 ns.delete_order_item_row = function(clicked) {
409 var row = $(clicked).parents("tbody").first();
412 ns.renumber_positions();
413 ns.recalc_amounts_and_taxes();
416 ns.row_table_scroll_down = function() {
417 $('#row_table_scroll_id').scrollTop($('#row_table_scroll_id')[0].scrollHeight);
420 ns.show_longdescription_dialog = function(clicked) {
421 var row = $(clicked).parents("tbody").first();
422 var position = $(row).find('[name="position"]').html();
423 var partnumber = $(row).find('[name="partnumber"]').html();
424 var description_elt = $(row).find('[name="order.orderitems[].description"]');
425 var description = description_elt.val();
426 var longdescription_elt = $(row).find('[name="order.orderitems[].longdescription"]');
429 if (!longdescription_elt.length) {
431 { name: 'action', value: 'Order/get_item_longdescription' },
432 { name: 'type', value: $('#type').val() },
433 { name: 'item_id', value: $(row).find('[name="order.orderitems[+].id"]').val() },
434 { name: 'parts_id', value: $(row).find('[name="order.orderitems[].parts_id"]').val() }
438 url: 'controller.pl',
443 success: function(val) {
444 longdescription = val;
448 longdescription = longdescription_elt.val();
452 runningnumber: position,
453 partnumber: partnumber,
454 description: description,
455 default_longdescription: longdescription,
456 set_function: function(val) {
457 longdescription_elt.remove();
458 $('<input type="hidden" name="order.orderitems[].longdescription">').insertAfter(description_elt).val(val);
462 kivi.SalesPurchase.edit_longdescription_with_params(params);
465 ns.price_chooser_item_row = function(clicked) {
466 if (!ns.check_cv()) return;
467 var row = $(clicked).parents("tbody").first();
468 var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
470 var data = $('#order_form').serializeArray();
471 data.push({ name: 'action', value: 'Order/price_popup' },
472 { name: 'item_id', value: item_id_dom.val() });
474 $.post("controller.pl", data, kivi.eval_json_result);
477 ns.update_price_source = function(item_id, source, descr, price_str, price_editable) {
478 var row = $('#item_' + item_id).parents("tbody").first();
479 var source_elt = $(row).find('[name="order.orderitems[].active_price_source"]');
480 var button_elt = $(row).find('[name="price_chooser_button"]');
482 button_elt.val(button_elt.val().replace(/.*\|/, descr + " |"));
483 source_elt.val(source);
485 var editable_div_elt = $(row).find('[name="editable_price"]');
486 var not_editable_div_elt = $(row).find('[name="not_editable_price"]');
487 if (price_editable == 1 && source === '') {
489 $(editable_div_elt).show();
490 $(not_editable_div_elt).hide();
491 $(editable_div_elt).find(':input').prop("disabled", false);
492 $(not_editable_div_elt).find(':input').prop("disabled", true);
495 $(editable_div_elt).hide();
496 $(not_editable_div_elt).show();
497 $(editable_div_elt).find(':input').prop("disabled", true);
498 $(not_editable_div_elt).find(':input').prop("disabled", false);
502 var price_elt = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
503 var html_elt = $(row).find('[name="sellprice_text"]');
504 price_elt.val(price_str);
505 html_elt.html(price_str);
506 ns.recalc_amounts_and_taxes();
509 kivi.io.close_dialog();
512 ns.update_discount_source = function(item_id, source, descr, discount_str, price_editable) {
513 var row = $('#item_' + item_id).parents("tbody").first();
514 var source_elt = $(row).find('[name="order.orderitems[].active_discount_source"]');
515 var button_elt = $(row).find('[name="price_chooser_button"]');
517 button_elt.val(button_elt.val().replace(/\|.*/, "| " + descr));
518 source_elt.val(source);
520 var editable_div_elt = $(row).find('[name="editable_discount"]');
521 var not_editable_div_elt = $(row).find('[name="not_editable_discount"]');
522 if (price_editable == 1 && source === '') {
524 $(editable_div_elt).show();
525 $(not_editable_div_elt).hide();
526 $(editable_div_elt).find(':input').prop("disabled", false);
527 $(not_editable_div_elt).find(':input').prop("disabled", true);
530 $(editable_div_elt).hide();
531 $(not_editable_div_elt).show();
532 $(editable_div_elt).find(':input').prop("disabled", true);
533 $(not_editable_div_elt).find(':input').prop("disabled", false);
537 var discount_elt = $(row).find('[name="order.orderitems[].discount_as_percent"]');
538 var html_elt = $(row).find('[name="discount_text"]');
539 discount_elt.val(discount_str);
540 html_elt.html(discount_str);
541 ns.recalc_amounts_and_taxes();
544 kivi.io.close_dialog();
547 ns.show_periodic_invoices_config_dialog = function() {
548 if ($('#type').val() !== 'sales_order') return;
551 url: 'controller.pl?action=Order/show_periodic_invoices_config_dialog',
552 data: { type: $('#type').val(),
554 config: $('#order_periodic_invoices_config').val(),
555 customer_id: $('#order_customer_id').val(),
556 transdate: $('#order_transdate').val(),
557 language_id: $('#language_id').val()
559 id: 'jq_periodic_invoices_config_dialog',
560 load: kivi.reinit_widgets,
562 title: kivi.t8('Edit the configuration for periodic invoices'),
570 ns.close_periodic_invoices_config_dialog = function() {
571 $('#jq_periodic_invoices_config_dialog').dialog('close');
574 ns.assign_periodic_invoices_config = function() {
575 var data = $('[name="Form"]').serializeArray();
576 data.push({ name: 'type', value: $('#type').val() },
577 { name: 'action', value: 'Order/assign_periodic_invoices_config' });
578 $.post("controller.pl", data, kivi.eval_json_result);
581 ns.check_save_active_periodic_invoices = function() {
582 var type = $('#type').val();
583 if (type !== 'sales_order') return true;
587 url: 'controller.pl',
588 data: { action: 'Order/get_has_active_periodic_invoices',
591 config: $('#order_periodic_invoices_config').val(),
596 success: function(val) {
602 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?'));
608 ns.show_vc_details_dialog = function() {
609 if (!ns.check_cv()) return;
613 if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
615 vc_id = $('#order_customer_id').val();
616 title = kivi.t8('Customer details');
619 vc_id = $('#order_vendor_id').val();
620 title = kivi.t8('Vendor details');
624 url: 'controller.pl',
625 data: { action: 'Order/show_customer_vendor_details_dialog',
626 type : $('#type').val(),
630 id: 'jq_customer_vendor_details_dialog',
640 ns.show_calculate_qty_dialog = function(clicked) {
641 var row = $(clicked).parents("tbody").first();
642 var input_id = $(row).find('[name="order.orderitems[].qty_as_number"]').attr('id');
643 var formula_id = $(row).find('[name="formula[+]"]').attr('id');
645 calculate_qty_selection_dialog("", input_id, "", formula_id);
652 if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
653 $('#order_customer_id').change(kivi.Order.reload_cv_dependant_selections);
655 $('#order_vendor_id').change(kivi.Order.reload_cv_dependant_selections);
658 if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
659 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_sellprice_as_number').val(kivi.format_amount(o.sellprice, -2)) });
661 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_sellprice_as_number').val(kivi.format_amount(o.lastcost, -2)) });
663 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_description').val(o.description) });
664 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_unit').val(o.unit) });
666 $('.add_item_input').keydown(function(event) {
667 if (event.keyCode == 13) {
668 event.preventDefault();
669 kivi.Order.add_item();
674 kivi.Order.init_row_handlers();
676 $('#row_table_id').on('sortstop', function(event, ui) {
677 $('#row_table_id thead a img').remove();
678 kivi.Order.renumber_positions();
681 $('#expand_all').on('click', function(event) {
682 event.preventDefault();
683 if ($('#expand_all').data('expanded') == 1) {
684 $('#expand_all').data('expanded', 0);
685 $('#expand_all').attr('src', 'image/expand.svg');
686 $('#expand_all').attr('alt', kivi.t8('Show all details'));
687 $('#expand_all').attr('title', kivi.t8('Show all details'));
688 $('.row_entry').each(function(idx, elt) {
689 kivi.Order.hide_second_row(elt);
692 $('#expand_all').data('expanded', 1);
693 $('#expand_all').attr('src', "image/collapse.svg");
694 $('#expand_all').attr('alt', kivi.t8('Hide all details'));
695 $('#expand_all').attr('title', kivi.t8('Hide all details'));
696 kivi.Order.load_all_second_rows();
697 $('.row_entry').each(function(idx, elt) {
698 kivi.Order.show_second_row(elt);