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 var row = $(clicked).parents("tbody").first();
454 var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
456 var data = $('#order_form').serializeArray();
457 data.push({ name: 'action', value: 'Order/price_popup' });
458 data.push({ name: 'item_id', value: item_id_dom.val() });
460 $.post("controller.pl", data, kivi.eval_json_result);
463 ns.update_price_source = function(item_id, source, descr, price_str, price_editable) {
464 var row = $('#item_' + item_id).parents("tbody").first();
465 var source_elt = $(row).find('[name="order.orderitems[].active_price_source"]');
466 var button_elt = $(row).find('[name="price_chooser_button"]');
468 button_elt.val(button_elt.val().replace(/.*\|/, descr + " |"));
469 source_elt.val(source);
471 var editable_div_elt = $(row).find('[name="editable_price"]');
472 var not_editable_div_elt = $(row).find('[name="not_editable_price"]');
473 if (price_editable == 1 && source === '') {
475 $(editable_div_elt).show();
476 $(not_editable_div_elt).hide();
477 $(editable_div_elt).find(':input').prop("disabled", false);
478 $(not_editable_div_elt).find(':input').prop("disabled", true);
481 $(editable_div_elt).hide();
482 $(not_editable_div_elt).show();
483 $(editable_div_elt).find(':input').prop("disabled", true);
484 $(not_editable_div_elt).find(':input').prop("disabled", false);
488 var price_elt = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
489 var html_elt = $(row).find('[name="sellprice_text"]');
490 price_elt.val(price_str);
491 html_elt.html(price_str);
492 ns.recalc_amounts_and_taxes();
495 kivi.io.close_dialog();
498 ns.update_discount_source = function(item_id, source, descr, discount_str, price_editable) {
499 var row = $('#item_' + item_id).parents("tbody").first();
500 var source_elt = $(row).find('[name="order.orderitems[].active_discount_source"]');
501 var button_elt = $(row).find('[name="price_chooser_button"]');
503 button_elt.val(button_elt.val().replace(/\|.*/, "| " + descr));
504 source_elt.val(source);
506 var editable_div_elt = $(row).find('[name="editable_discount"]');
507 var not_editable_div_elt = $(row).find('[name="not_editable_discount"]');
508 if (price_editable == 1 && source === '') {
510 $(editable_div_elt).show();
511 $(not_editable_div_elt).hide();
512 $(editable_div_elt).find(':input').prop("disabled", false);
513 $(not_editable_div_elt).find(':input').prop("disabled", true);
516 $(editable_div_elt).hide();
517 $(not_editable_div_elt).show();
518 $(editable_div_elt).find(':input').prop("disabled", true);
519 $(not_editable_div_elt).find(':input').prop("disabled", false);
523 var discount_elt = $(row).find('[name="order.orderitems[].discount_as_percent"]');
524 var html_elt = $(row).find('[name="discount_text"]');
525 discount_elt.val(discount_str);
526 html_elt.html(discount_str);
527 ns.recalc_amounts_and_taxes();
530 kivi.io.close_dialog();
533 ns.show_periodic_invoices_config_dialog = function() {
534 if ($('#type').val() !== 'sales_order') return;
537 url: 'controller.pl?action=Order/show_periodic_invoices_config_dialog',
538 data: { type : $('#type').val(),
540 config : $('#order_periodic_invoices_config').val(),
541 customer_id: $('#order_customer_id').val(),
542 transdate : $('#order_transdate').val(),
543 language_id: $('#language_id').val()
545 id: 'jq_periodic_invoices_config_dialog',
546 load: kivi.reinit_widgets,
548 title: kivi.t8('Edit the configuration for periodic invoices'),
556 ns.close_periodic_invoices_config_dialog = function() {
557 $('#jq_periodic_invoices_config_dialog').dialog('close');
560 ns.assign_periodic_invoices_config = function() {
561 var data = $('[name="Form"]').serializeArray();
562 data.push({ name: 'type', value: $('#type').val() });
563 data.push({ name: 'action', value: 'Order/assign_periodic_invoices_config' });
564 $.post("controller.pl", data, kivi.eval_json_result);
567 ns.check_save_active_periodic_invoices = function() {
568 var type = $('#type').val();
569 if (type !== 'sales_order') return true;
573 url: 'controller.pl',
574 data: { action: 'Order/get_has_active_periodic_invoices',
577 config: $('#order_periodic_invoices_config').val(),
582 success: function(val){
588 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?'));
594 ns.show_vc_details_dialog = function() {
595 if (!ns.check_cv()) return;
599 if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
601 vc_id = $('#order_customer_id').val();
602 title = kivi.t8('Customer details');
605 vc_id = $('#order_vendor_id').val();
606 title = kivi.t8('Vendor details');
610 url: 'controller.pl',
611 data: { action: 'Order/show_customer_vendor_details_dialog',
612 type : $('#type').val(),
616 id: 'jq_customer_vendor_details_dialog',
629 if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
630 $('#order_customer_id').change(kivi.Order.reload_cv_dependant_selections);
632 $('#order_vendor_id').change(kivi.Order.reload_cv_dependant_selections);
635 if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
636 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_sellprice_as_number').val(kivi.format_amount(o.sellprice, -2)) });
638 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_sellprice_as_number').val(kivi.format_amount(o.lastcost, -2)) });
640 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_description').val(o.description) });
641 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_unit').val(o.unit) });
643 $('.add_item_input').keydown(function(event) {
644 if(event.keyCode == 13) {
645 event.preventDefault();
646 kivi.Order.add_item();
651 kivi.Order.init_row_handlers();
653 $('#row_table_id').on('sortstop', function(event, ui) {
654 $('#row_table_id thead a img').remove();
655 kivi.Order.renumber_positions();
658 $('#expand_all').on('click', function(event) {
659 event.preventDefault();
660 if ($('#expand_all').data('expanded') == 1) {
661 $('#expand_all').data('expanded', 0);
662 $('#expand_all').attr('src', 'image/expand.svg');
663 $('#expand_all').attr('alt', kivi.t8('Show all details'));
664 $('#expand_all').attr('title', kivi.t8('Show all details'));
665 $('.row_entry').each(function(idx, elt) {
666 kivi.Order.hide_second_row(elt);
669 $('#expand_all').data('expanded', 1);
670 $('#expand_all').attr('src', "image/collapse.svg");
671 $('#expand_all').attr('alt', kivi.t8('Hide all details'));
672 $('#expand_all').attr('title', kivi.t8('Hide all details'));
673 kivi.Order.load_all_second_rows();
674 $('.row_entry').each(function(idx, elt) {
675 kivi.Order.show_second_row(elt);