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(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/save' });
45 $.post("controller.pl", data, kivi.eval_json_result);
48 ns.save_as_new = function(warn_on_duplicates) {
49 if (!ns.check_cv()) return;
50 if (warn_on_duplicates && !ns.check_save_duplicate_parts()) return;
52 var data = $('#order_form').serializeArray();
53 data.push({ name: 'action', value: 'Order/save_as_new' });
55 $.post("controller.pl", data, kivi.eval_json_result);
58 ns.save_and_delivery_order = function(warn_on_duplicates) {
59 if (!ns.check_cv()) return;
60 if (warn_on_duplicates && !ns.check_save_duplicate_parts()) return;
62 var data = $('#order_form').serializeArray();
63 data.push({ name: 'action', value: 'Order/save_and_delivery_order' });
65 $.post("controller.pl", data, kivi.eval_json_result);
68 ns.save_and_invoice = function(warn_on_duplicates) {
69 if (!ns.check_cv()) return;
70 if (warn_on_duplicates && !ns.check_save_duplicate_parts()) return;
72 var data = $('#order_form').serializeArray();
73 data.push({ name: 'action', value: 'Order/save_and_invoice' });
75 $.post("controller.pl", data, kivi.eval_json_result);
78 ns.delete_order = function() {
79 var data = $('#order_form').serializeArray();
80 data.push({ name: 'action', value: 'Order/delete' });
82 $.post("controller.pl", data, kivi.eval_json_result);
85 ns.show_print_options = function() {
86 if (!ns.check_cv()) return;
91 title: kivi.t8('Print options'),
98 ns.print = function() {
99 $('#print_options').dialog('close');
101 var data = $('#order_form').serializeArray();
102 data = data.concat($('#print_options_form').serializeArray());
103 data.push({ name: 'action', value: 'Order/print' });
105 $.post("controller.pl", data, kivi.eval_json_result);
108 ns.download_pdf = function(pdf_filename, key) {
110 data.push({ name: 'action', value: 'Order/download_pdf' });
111 data.push({ name: 'type', value: $('#type').val() });
112 data.push({ name: 'pdf_filename', value: pdf_filename });
113 data.push({ name: 'key', value: key });
114 $.download("controller.pl", data);
117 ns.email = function() {
118 if (!ns.check_cv()) return;
119 var data = $('#order_form').serializeArray();
120 data.push({ name: 'action', value: 'Order/show_email_dialog' });
122 $.post("controller.pl", data, kivi.eval_json_result);
127 ns.setup_send_email_dialog = function() {
128 kivi.SalesPurchase.show_all_print_options_elements();
129 kivi.SalesPurchase.show_print_options_elements([ 'sendmode', 'media', 'copies', 'remove_draft' ], false);
131 $('#print_options_form table').first().remove().appendTo('#email_form_print_options');
133 var to_focus = $('#email_form_to').val() === '' ? 'to' : 'subject';
134 $('#email_form_' + to_focus).focus();
137 ns.finish_send_email_dialog = function() {
138 kivi.SalesPurchase.show_all_print_options_elements();
140 $('#email_form_print_options table').first().remove().prependTo('#print_options_form');
144 ns.show_email_dialog = function(html) {
145 var id = 'send_email_dialog';
146 var dialog_params = {
150 title: kivi.t8('Send email'),
152 beforeClose: kivi.Order.finish_send_email_dialog,
153 close: function(event, ui) {
154 email_dialog.remove();
158 $('#' + id).remove();
160 email_dialog = $('<div style="display:none" id="' + id + '"></div>').appendTo('body');
161 email_dialog.html(html);
162 email_dialog.dialog(dialog_params);
164 kivi.Order.setup_send_email_dialog();
166 $('.cancel').click(ns.close_email_dialog);
171 ns.send_email = function() {
172 var data = $('#order_form').serializeArray();
173 data = data.concat($('[name^="email_form."]').serializeArray());
174 data = data.concat($('[name^="print_options."]').serializeArray());
175 data.push({ name: 'action', value: 'Order/send_email' });
176 $.post("controller.pl", data, kivi.eval_json_result);
179 ns.close_email_dialog = function() {
180 email_dialog.dialog("close");
183 ns.reload_cv_dependant_selections = function() {
184 var data = $('#order_form').serializeArray();
185 data.push({ name: 'action', value: 'Order/customer_vendor_changed' });
187 $.post("controller.pl", data, kivi.eval_json_result);
190 ns.reformat_number = function(event) {
191 $(event.target).val(kivi.format_amount(kivi.parse_amount($(event.target).val()), -2));
194 ns.recalc_amounts_and_taxes = function() {
195 var data = $('#order_form').serializeArray();
196 data.push({ name: 'action', value: 'Order/recalc_amounts_and_taxes' });
198 $.post("controller.pl", data, kivi.eval_json_result);
201 ns.unit_change = function(event) {
202 var row = $(event.target).parents("tbody").first();
203 var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
204 var sellprice_dom = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
205 var select_elt = $(row).find('[name="order.orderitems[].unit"]');
207 var oldval = $(select_elt).data('oldval');
208 $(select_elt).data('oldval', $(select_elt).val());
210 var data = $('#order_form').serializeArray();
211 data.push({ name: 'action', value: 'Order/unit_changed' });
212 data.push({ name: 'item_id', value: item_id_dom.val() });
213 data.push({ name: 'old_unit', value: oldval });
214 data.push({ name: 'sellprice_dom_id', value: sellprice_dom.attr('id') });
216 $.post("controller.pl", data, kivi.eval_json_result);
219 ns.update_sellprice = function(item_id, price_str) {
220 var row = $('#item_' + item_id).parents("tbody").first();
221 var price_elt = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
222 var html_elt = $(row).find('[name="sellprice_text"]');
223 price_elt.val(price_str);
224 html_elt.html(price_str);
227 ns.load_second_row = function(row) {
228 var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
229 var div_elt = $(row).find('[name="second_row"]');
231 if ($(div_elt).data('loaded') == 1) {
234 var data = $('#order_form').serializeArray();
235 data.push({ name: 'action', value: 'Order/load_second_rows' });
236 data.push({ name: 'item_ids[]', value: item_id_dom.val() });
238 $.post("controller.pl", data, kivi.eval_json_result);
241 ns.load_all_second_rows = function() {
242 var rows = $('.row_entry').filter(function(idx, elt) {
243 return $(elt).find('[name="second_row"]').data('loaded') != 1;
246 var item_ids = $.map(rows, function(elt) {
247 var item_id = $(elt).find('[name="orderitem_ids[+]"]').val();
248 return { name: 'item_ids[]', value: item_id };
251 if (item_ids.length == 0) {
255 var data = $('#order_form').serializeArray();
256 data.push({ name: 'action', value: 'Order/load_second_rows' });
257 data = data.concat(item_ids);
259 $.post("controller.pl", data, kivi.eval_json_result);
262 ns.hide_second_row = function(row) {
263 $(row).children().not(':first').hide();
264 $(row).data('expanded', 0);
265 var elt = $(row).find('.expand');
266 elt.attr('src', "image/expand.svg");
267 elt.attr('alt', kivi.t8('Show details'));
268 elt.attr('title', kivi.t8('Show details'));
271 ns.show_second_row = function(row) {
272 $(row).children().not(':first').show();
273 $(row).data('expanded', 1);
274 var elt = $(row).find('.expand');
275 elt.attr('src', "image/collapse.svg");
276 elt.attr('alt', kivi.t8('Hide details'));
277 elt.attr('title', kivi.t8('Hide details'));
280 ns.toggle_second_row = function(row) {
281 if ($(row).data('expanded') == 1) {
282 ns.hide_second_row(row);
284 ns.show_second_row(row);
288 ns.init_row_handlers = function() {
289 kivi.run_once_for('.recalc', 'on_change_recalc', function(elt) {
290 $(elt).change(ns.recalc_amounts_and_taxes);
293 kivi.run_once_for('.reformat_number', 'on_change_reformat', function(elt) {
294 $(elt).change(ns.reformat_number);
297 kivi.run_once_for('.unitselect', 'on_change_unit_with_oldval', function(elt) {
298 $(elt).data('oldval', $(elt).val());
299 $(elt).change(ns.unit_change);
302 kivi.run_once_for('.row_entry', 'on_kbd_click_show_hide', function(elt) {
303 $(elt).keydown(function(event) {
304 if(event.keyCode == 40 && event.shiftKey === true) {
306 event.preventDefault();
307 var row = $(event.target).parents(".row_entry").first();
308 ns.load_second_row(row);
309 ns.show_second_row(row);
312 if(event.keyCode == 38 && event.shiftKey === true) {
314 event.preventDefault();
315 var row = $(event.target).parents(".row_entry").first();
316 ns.hide_second_row(row);
322 kivi.run_once_for('.expand', 'expand_second_row', function(elt) {
323 $(elt).click(function(event) {
324 event.preventDefault();
325 var row = $(event.target).parents(".row_entry").first();
326 ns.load_second_row(row);
327 ns.toggle_second_row(row);
334 ns.redisplay_line_values = function(is_sales, data) {
335 $('.row_entry').each(function(idx, elt) {
336 $(elt).find('[name="linetotal"]').html(data[idx][0]);
337 if (is_sales && $(elt).find('[name="second_row"]').data('loaded') == 1) {
338 var mt = data[idx][1];
339 var mp = data[idx][2];
341 if (mt[0] === '-') h += ' class="plus0"';
342 h += '>' + mt + ' ' + mp + '%';
344 $(elt).find('[name="linemargin"]').html(h);
349 ns.renumber_positions = function() {
350 $('.row_entry [name="position"]').each(function(idx, elt) {
355 ns.reorder_items = function(order_by) {
356 var dir = $('#' + order_by + '_header_id a img').attr("data-sort-dir");
357 $('#row_table_id thead a img').remove();
362 src = "image/up.png";
365 src = "image/down.png";
368 $('#' + order_by + '_header_id a').append('<img border=0 data-sort-dir=' + dir + ' src=' + src + ' alt="' + kivi.t8('sort items') + '">');
370 var data = $('#order_form').serializeArray();
371 data.push({ name: 'action', value: 'Order/reorder_items' });
372 data.push({ name: 'order_by', value: order_by });
373 data.push({ name: 'sort_dir', value: dir });
375 $.post("controller.pl", data, kivi.eval_json_result);
378 ns.redisplay_items = function(data) {
379 var old_rows = $('.row_entry').detach();
381 $(data).each(function(idx, elt) {
382 new_rows.push(old_rows[elt.old_pos - 1]);
384 $(new_rows).appendTo($('#row_table_id'));
385 ns.renumber_positions();
388 ns.add_item = function() {
389 if ($('#add_item_parts_id').val() === '') return;
390 if (!ns.check_cv()) return;
392 $('#row_table_id thead a img').remove();
394 var data = $('#order_form').serializeArray();
395 data.push({ name: 'action', value: 'Order/add_item' });
397 $.post("controller.pl", data, kivi.eval_json_result);
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 callback: 'Order/add_multi_items',
409 callback_data_id: 'order_form' },
410 id: 'jq_multi_items_dialog',
412 title: kivi.t8('Add multiple items'),
420 ns.close_multi_items_dialog = function() {
421 $('#jq_multi_items_dialog').dialog('close');
424 ns.delete_order_item_row = function(clicked) {
425 var row = $(clicked).parents("tbody").first();
428 ns.renumber_positions();
429 ns.recalc_amounts_and_taxes();
432 ns.row_table_scroll_down = function() {
433 $('#row_table_scroll_id').scrollTop($('#row_table_scroll_id')[0].scrollHeight);
436 ns.show_longdescription_dialog = function(clicked) {
437 var row = $(clicked).parents("tbody").first();
438 var position = $(row).find('[name="position"]').html();
439 var partnumber = $(row).find('[name="partnumber"]').html();
440 var description_elt = $(row).find('[name="order.orderitems[].description"]');
441 var description = description_elt.val();
442 var longdescription_elt = $(row).find('[name="order.orderitems[].longdescription"]');
445 if (!longdescription_elt.length) {
447 data.push({ name: 'action', value: 'Order/get_item_longdescription' });
448 data.push({ name: 'type', value: $('#type').val() });
449 data.push({ name: 'item_id', value: $(row).find('[name="order.orderitems[+].id"]').val() });
450 data.push({ name: 'parts_id', value: $(row).find('[name="order.orderitems[].parts_id"]').val() });
452 url: 'controller.pl',
457 success: function(val){
458 longdescription = val;
462 longdescription = longdescription_elt.val();
465 var params = { runningnumber: position,
466 partnumber: partnumber,
467 description: description,
468 default_longdescription: longdescription,
469 set_function: function(val){
470 longdescription_elt.remove();
471 $('<input type="hidden" name="order.orderitems[].longdescription">').insertAfter(description_elt).val(val);
475 kivi.SalesPurchase.edit_longdescription_with_params(params);
478 ns.price_chooser_item_row = function(clicked) {
479 var row = $(clicked).parents("tbody").first();
480 var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
482 var data = $('#order_form').serializeArray();
483 data.push({ name: 'action', value: 'Order/price_popup' });
484 data.push({ name: 'item_id', value: item_id_dom.val() });
486 $.post("controller.pl", data, kivi.eval_json_result);
489 ns.update_price_source = function(item_id, source, descr, price_str, price_editable) {
490 var row = $('#item_' + item_id).parents("tbody").first();
491 var source_elt = $(row).find('[name="order.orderitems[].active_price_source"]');
492 var button_elt = $(row).find('[name="price_chooser_button"]');
494 button_elt.val(button_elt.val().replace(/.*\|/, descr + " |"));
495 source_elt.val(source);
497 var editable_div_elt = $(row).find('[name="editable_price"]');
498 var not_editable_div_elt = $(row).find('[name="not_editable_price"]');
499 if (price_editable == 1 && source === '') {
501 $(editable_div_elt).show();
502 $(not_editable_div_elt).hide();
503 $(editable_div_elt).find(':input').prop("disabled", false);
504 $(not_editable_div_elt).find(':input').prop("disabled", true);
507 $(editable_div_elt).hide();
508 $(not_editable_div_elt).show();
509 $(editable_div_elt).find(':input').prop("disabled", true);
510 $(not_editable_div_elt).find(':input').prop("disabled", false);
514 var price_elt = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
515 var html_elt = $(row).find('[name="sellprice_text"]');
516 price_elt.val(price_str);
517 html_elt.html(price_str);
518 ns.recalc_amounts_and_taxes();
521 kivi.io.close_dialog();
524 ns.update_discount_source = function(item_id, source, descr, discount_str, price_editable) {
525 var row = $('#item_' + item_id).parents("tbody").first();
526 var source_elt = $(row).find('[name="order.orderitems[].active_discount_source"]');
527 var button_elt = $(row).find('[name="price_chooser_button"]');
529 button_elt.val(button_elt.val().replace(/\|.*/, "| " + descr));
530 source_elt.val(source);
532 var editable_div_elt = $(row).find('[name="editable_discount"]');
533 var not_editable_div_elt = $(row).find('[name="not_editable_discount"]');
534 if (price_editable == 1 && source === '') {
536 $(editable_div_elt).show();
537 $(not_editable_div_elt).hide();
538 $(editable_div_elt).find(':input').prop("disabled", false);
539 $(not_editable_div_elt).find(':input').prop("disabled", true);
542 $(editable_div_elt).hide();
543 $(not_editable_div_elt).show();
544 $(editable_div_elt).find(':input').prop("disabled", true);
545 $(not_editable_div_elt).find(':input').prop("disabled", false);
549 var discount_elt = $(row).find('[name="order.orderitems[].discount_as_percent"]');
550 var html_elt = $(row).find('[name="discount_text"]');
551 discount_elt.val(discount_str);
552 html_elt.html(discount_str);
553 ns.recalc_amounts_and_taxes();
556 kivi.io.close_dialog();
559 ns.show_periodic_invoices_config_dialog = function() {
560 if ($('#type').val() !== 'sales_order') return;
563 url: 'controller.pl?action=Order/show_periodic_invoices_config_dialog',
564 data: { type : $('#type').val(),
566 config : $('#order_periodic_invoices_config').val(),
567 customer_id: $('#order_customer_id').val(),
568 transdate : $('#order_transdate').val(),
569 language_id: $('#language_id').val()
571 id: 'jq_periodic_invoices_config_dialog',
572 load: kivi.reinit_widgets,
574 title: kivi.t8('Edit the configuration for periodic invoices'),
582 ns.close_periodic_invoices_config_dialog = function() {
583 $('#jq_periodic_invoices_config_dialog').dialog('close');
586 ns.assign_periodic_invoices_config = function() {
587 var data = $('[name="Form"]').serializeArray();
588 data.push({ name: 'type', value: $('#type').val() });
589 data.push({ name: 'action', value: 'Order/assign_periodic_invoices_config' });
590 $.post("controller.pl", data, kivi.eval_json_result);
593 ns.check_save_active_periodic_invoices = function() {
594 var type = $('#type').val();
595 if (type !== 'sales_order') return true;
599 url: 'controller.pl',
600 data: { action: 'Order/get_has_active_periodic_invoices',
603 config: $('#order_periodic_invoices_config').val(),
608 success: function(val){
614 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?'));
623 if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
624 $('#order_customer_id').change(kivi.Order.reload_cv_dependant_selections);
626 $('#order_vendor_id').change(kivi.Order.reload_cv_dependant_selections);
629 if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
630 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_sellprice_as_number').val(kivi.format_amount(o.sellprice, -2)) });
632 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_sellprice_as_number').val(kivi.format_amount(o.lastcost, -2)) });
634 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_description').val(o.description) });
635 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_unit').val(o.unit) });
637 $('.add_item_input').keydown(function(event) {
638 if(event.keyCode == 13) {
639 event.preventDefault();
640 kivi.Order.add_item();
645 kivi.Order.init_row_handlers();
647 $('#row_table_id').on('sortstop', function(event, ui) {
648 $('#row_table_id thead a img').remove();
649 kivi.Order.renumber_positions();
652 $('#expand_all').on('click', function(event) {
653 event.preventDefault();
654 if ($('#expand_all').data('expanded') == 1) {
655 $('#expand_all').data('expanded', 0);
656 $('#expand_all').attr('src', 'image/expand.svg');
657 $('#expand_all').attr('alt', kivi.t8('Show all details'));
658 $('#expand_all').attr('title', kivi.t8('Show all details'));
659 $('.row_entry').each(function(idx, elt) {
660 kivi.Order.hide_second_row(elt);
663 $('#expand_all').data('expanded', 1);
664 $('#expand_all').attr('src', "image/collapse.svg");
665 $('#expand_all').attr('alt', kivi.t8('Hide all details'));
666 $('#expand_all').attr('title', kivi.t8('Hide all details'));
667 kivi.Order.load_all_second_rows();
668 $('.row_entry').each(function(idx, elt) {
669 kivi.Order.show_second_row(elt);