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.reload_cv_dependant_selections = function() {
154 var data = $('#order_form').serializeArray();
155 data.push({ name: 'action', value: 'Order/customer_vendor_changed' });
157 $.post("controller.pl", data, kivi.eval_json_result);
160 ns.reformat_number = function(event) {
161 $(event.target).val(kivi.format_amount(kivi.parse_amount($(event.target).val()), -2));
164 ns.recalc_amounts_and_taxes = function() {
165 var data = $('#order_form').serializeArray();
166 data.push({ name: 'action', value: 'Order/recalc_amounts_and_taxes' });
168 $.post("controller.pl", data, kivi.eval_json_result);
171 ns.unit_change = function(event) {
172 var row = $(event.target).parents("tbody").first();
173 var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
174 var sellprice_dom = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
175 var select_elt = $(row).find('[name="order.orderitems[].unit"]');
177 var oldval = $(select_elt).data('oldval');
178 $(select_elt).data('oldval', $(select_elt).val());
180 var data = $('#order_form').serializeArray();
181 data.push({ name: 'action', value: 'Order/unit_changed' });
182 data.push({ name: 'item_id', value: item_id_dom.val() });
183 data.push({ name: 'old_unit', value: oldval });
184 data.push({ name: 'sellprice_dom_id', value: sellprice_dom.attr('id') });
186 $.post("controller.pl", data, kivi.eval_json_result);
189 ns.update_sellprice = function(item_id, price_str) {
190 var row = $('#item_' + item_id).parents("tbody").first();
191 var price_elt = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
192 var html_elt = $(row).find('[name="sellprice_text"]');
193 price_elt.val(price_str);
194 html_elt.html(price_str);
197 ns.load_second_row = function(row) {
198 var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
199 var div_elt = $(row).find('[name="second_row"]');
201 if ($(div_elt).data('loaded') == 1) {
204 var data = $('#order_form').serializeArray();
205 data.push({ name: 'action', value: 'Order/load_second_rows' });
206 data.push({ name: 'item_ids[]', value: item_id_dom.val() });
208 $.post("controller.pl", data, kivi.eval_json_result);
211 ns.load_all_second_rows = function() {
212 var rows = $('.row_entry').filter(function(idx, elt) {
213 return $(elt).find('[name="second_row"]').data('loaded') != 1;
216 var item_ids = $.map(rows, function(elt) {
217 var item_id = $(elt).find('[name="orderitem_ids[+]"]').val();
218 return { name: 'item_ids[]', value: item_id };
221 if (item_ids.length == 0) {
225 var data = $('#order_form').serializeArray();
226 data.push({ name: 'action', value: 'Order/load_second_rows' });
227 data = data.concat(item_ids);
229 $.post("controller.pl", data, kivi.eval_json_result);
232 ns.hide_second_row = function(row) {
233 $(row).children().not(':first').hide();
234 $(row).data('expanded', 0);
235 var elt = $(row).find('.expand');
236 elt.attr('src', "image/expand.svg");
237 elt.attr('alt', kivi.t8('Show details'));
238 elt.attr('title', kivi.t8('Show details'));
241 ns.show_second_row = function(row) {
242 $(row).children().not(':first').show();
243 $(row).data('expanded', 1);
244 var elt = $(row).find('.expand');
245 elt.attr('src', "image/collapse.svg");
246 elt.attr('alt', kivi.t8('Hide details'));
247 elt.attr('title', kivi.t8('Hide details'));
250 ns.toggle_second_row = function(row) {
251 if ($(row).data('expanded') == 1) {
252 ns.hide_second_row(row);
254 ns.show_second_row(row);
258 ns.init_row_handlers = function() {
259 kivi.run_once_for('.recalc', 'on_change_recalc', function(elt) {
260 $(elt).change(ns.recalc_amounts_and_taxes);
263 kivi.run_once_for('.reformat_number', 'on_change_reformat', function(elt) {
264 $(elt).change(ns.reformat_number);
267 kivi.run_once_for('.unitselect', 'on_change_unit_with_oldval', function(elt) {
268 $(elt).data('oldval', $(elt).val());
269 $(elt).change(ns.unit_change);
272 kivi.run_once_for('.row_entry', 'on_kbd_click_show_hide', function(elt) {
273 $(elt).keydown(function(event) {
274 if(event.keyCode == 40 && event.shiftKey === true) {
276 event.preventDefault();
277 var row = $(event.target).parents(".row_entry").first();
278 ns.load_second_row(row);
279 ns.show_second_row(row);
282 if(event.keyCode == 38 && event.shiftKey === true) {
284 event.preventDefault();
285 var row = $(event.target).parents(".row_entry").first();
286 ns.hide_second_row(row);
292 kivi.run_once_for('.expand', 'expand_second_row', function(elt) {
293 $(elt).click(function(event) {
294 event.preventDefault();
295 var row = $(event.target).parents(".row_entry").first();
296 ns.load_second_row(row);
297 ns.toggle_second_row(row);
304 ns.redisplay_line_values = function(is_sales, data) {
305 $('.row_entry').each(function(idx, elt) {
306 $(elt).find('[name="linetotal"]').html(data[idx][0]);
307 if (is_sales && $(elt).find('[name="second_row"]').data('loaded') == 1) {
308 var mt = data[idx][1];
309 var mp = data[idx][2];
311 if (mt[0] === '-') h += ' class="plus0"';
312 h += '>' + mt + ' ' + mp + '%';
314 $(elt).find('[name="linemargin"]').html(h);
319 ns.renumber_positions = function() {
320 $('.row_entry [name="position"]').each(function(idx, elt) {
325 ns.reorder_items = function(order_by) {
326 var dir = $('#' + order_by + '_header_id a img').attr("data-sort-dir");
327 $('#row_table_id thead a img').remove();
332 src = "image/up.png";
335 src = "image/down.png";
338 $('#' + order_by + '_header_id a').append('<img border=0 data-sort-dir=' + dir + ' src=' + src + ' alt="' + kivi.t8('sort items') + '">');
340 var data = $('#order_form').serializeArray();
341 data.push({ name: 'action', value: 'Order/reorder_items' });
342 data.push({ name: 'order_by', value: order_by });
343 data.push({ name: 'sort_dir', value: dir });
345 $.post("controller.pl", data, kivi.eval_json_result);
348 ns.redisplay_items = function(data) {
349 var old_rows = $('.row_entry').detach();
351 $(data).each(function(idx, elt) {
352 new_rows.push(old_rows[elt.old_pos - 1]);
354 $(new_rows).appendTo($('#row_table_id'));
355 ns.renumber_positions();
358 ns.add_item = function() {
359 if ($('#add_item_parts_id').val() === '') return;
360 if (!ns.check_cv()) return;
362 $('#row_table_id thead a img').remove();
364 var data = $('#order_form').serializeArray();
365 data.push({ name: 'action', value: 'Order/add_item' });
367 $.post("controller.pl", data, kivi.eval_json_result);
370 ns.show_multi_items_dialog = function() {
371 if (!ns.check_cv()) return;
373 $('#row_table_id thead a img').remove();
376 url: 'controller.pl?action=Order/show_multi_items_dialog',
377 data: { type: $('#type').val(),
378 callback: 'Order/add_multi_items',
379 callback_data_id: 'order_form' },
380 id: 'jq_multi_items_dialog',
382 title: kivi.t8('Add multiple items'),
390 ns.close_multi_items_dialog = function() {
391 $('#jq_multi_items_dialog').dialog('close');
394 ns.delete_order_item_row = function(clicked) {
395 var row = $(clicked).parents("tbody").first();
398 ns.renumber_positions();
399 ns.recalc_amounts_and_taxes();
402 ns.row_table_scroll_down = function() {
403 $('#row_table_scroll_id').scrollTop($('#row_table_scroll_id')[0].scrollHeight);
406 ns.show_longdescription_dialog = function(clicked) {
407 var row = $(clicked).parents("tbody").first();
408 var position = $(row).find('[name="position"]').html();
409 var partnumber = $(row).find('[name="partnumber"]').html();
410 var description_elt = $(row).find('[name="order.orderitems[].description"]');
411 var description = description_elt.val();
412 var longdescription_elt = $(row).find('[name="order.orderitems[].longdescription"]');
415 if (!longdescription_elt.length) {
417 data.push({ name: 'action', value: 'Order/get_item_longdescription' });
418 data.push({ name: 'type', value: $('#type').val() });
419 data.push({ name: 'item_id', value: $(row).find('[name="order.orderitems[+].id"]').val() });
420 data.push({ name: 'parts_id', value: $(row).find('[name="order.orderitems[].parts_id"]').val() });
422 url: 'controller.pl',
427 success: function(val){
428 longdescription = val;
432 longdescription = longdescription_elt.val();
435 var params = { runningnumber: position,
436 partnumber: partnumber,
437 description: description,
438 default_longdescription: longdescription,
439 set_function: function(val){
440 longdescription_elt.remove();
441 $('<input type="hidden" name="order.orderitems[].longdescription">').insertAfter(description_elt).val(val);
445 kivi.SalesPurchase.edit_longdescription_with_params(params);
448 ns.price_chooser_item_row = function(clicked) {
449 var row = $(clicked).parents("tbody").first();
450 var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
452 var data = $('#order_form').serializeArray();
453 data.push({ name: 'action', value: 'Order/price_popup' });
454 data.push({ name: 'item_id', value: item_id_dom.val() });
456 $.post("controller.pl", data, kivi.eval_json_result);
459 ns.update_price_source = function(item_id, source, descr, price_str, price_editable) {
460 var row = $('#item_' + item_id).parents("tbody").first();
461 var source_elt = $(row).find('[name="order.orderitems[].active_price_source"]');
462 var button_elt = $(row).find('[name="price_chooser_button"]');
464 button_elt.val(button_elt.val().replace(/.*\|/, descr + " |"));
465 source_elt.val(source);
467 var editable_div_elt = $(row).find('[name="editable_price"]');
468 var not_editable_div_elt = $(row).find('[name="not_editable_price"]');
469 if (price_editable == 1 && source === '') {
471 $(editable_div_elt).show();
472 $(not_editable_div_elt).hide();
473 $(editable_div_elt).find(':input').prop("disabled", false);
474 $(not_editable_div_elt).find(':input').prop("disabled", true);
477 $(editable_div_elt).hide();
478 $(not_editable_div_elt).show();
479 $(editable_div_elt).find(':input').prop("disabled", true);
480 $(not_editable_div_elt).find(':input').prop("disabled", false);
484 var price_elt = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
485 var html_elt = $(row).find('[name="sellprice_text"]');
486 price_elt.val(price_str);
487 html_elt.html(price_str);
488 ns.recalc_amounts_and_taxes();
491 kivi.io.close_dialog();
494 ns.update_discount_source = function(item_id, source, descr, discount_str, price_editable) {
495 var row = $('#item_' + item_id).parents("tbody").first();
496 var source_elt = $(row).find('[name="order.orderitems[].active_discount_source"]');
497 var button_elt = $(row).find('[name="price_chooser_button"]');
499 button_elt.val(button_elt.val().replace(/\|.*/, "| " + descr));
500 source_elt.val(source);
502 var editable_div_elt = $(row).find('[name="editable_discount"]');
503 var not_editable_div_elt = $(row).find('[name="not_editable_discount"]');
504 if (price_editable == 1 && source === '') {
506 $(editable_div_elt).show();
507 $(not_editable_div_elt).hide();
508 $(editable_div_elt).find(':input').prop("disabled", false);
509 $(not_editable_div_elt).find(':input').prop("disabled", true);
512 $(editable_div_elt).hide();
513 $(not_editable_div_elt).show();
514 $(editable_div_elt).find(':input').prop("disabled", true);
515 $(not_editable_div_elt).find(':input').prop("disabled", false);
519 var discount_elt = $(row).find('[name="order.orderitems[].discount_as_percent"]');
520 var html_elt = $(row).find('[name="discount_text"]');
521 discount_elt.val(discount_str);
522 html_elt.html(discount_str);
523 ns.recalc_amounts_and_taxes();
526 kivi.io.close_dialog();
529 ns.show_periodic_invoices_config_dialog = function() {
530 if ($('#type').val() !== 'sales_order') return;
533 url: 'controller.pl?action=Order/show_periodic_invoices_config_dialog',
534 data: { type : $('#type').val(),
536 config : $('#order_periodic_invoices_config').val(),
537 customer_id: $('#order_customer_id').val(),
538 transdate : $('#order_transdate').val(),
539 language_id: $('#language_id').val()
541 id: 'jq_periodic_invoices_config_dialog',
542 load: kivi.reinit_widgets,
544 title: kivi.t8('Edit the configuration for periodic invoices'),
552 ns.close_periodic_invoices_config_dialog = function() {
553 $('#jq_periodic_invoices_config_dialog').dialog('close');
556 ns.assign_periodic_invoices_config = function() {
557 var data = $('[name="Form"]').serializeArray();
558 data.push({ name: 'type', value: $('#type').val() });
559 data.push({ name: 'action', value: 'Order/assign_periodic_invoices_config' });
560 $.post("controller.pl", data, kivi.eval_json_result);
563 ns.check_save_active_periodic_invoices = function() {
564 var type = $('#type').val();
565 if (type !== 'sales_order') return true;
569 url: 'controller.pl',
570 data: { action: 'Order/get_has_active_periodic_invoices',
573 config: $('#order_periodic_invoices_config').val(),
578 success: function(val){
584 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?'));
593 if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
594 $('#order_customer_id').change(kivi.Order.reload_cv_dependant_selections);
596 $('#order_vendor_id').change(kivi.Order.reload_cv_dependant_selections);
599 if ($('#type').val() == 'sales_order' || $('#type').val() == 'sales_quotation' ) {
600 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_sellprice_as_number').val(kivi.format_amount(o.sellprice, -2)) });
602 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_sellprice_as_number').val(kivi.format_amount(o.lastcost, -2)) });
604 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_description').val(o.description) });
605 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_unit').val(o.unit) });
607 $('.add_item_input').keydown(function(event) {
608 if(event.keyCode == 13) {
609 event.preventDefault();
610 kivi.Order.add_item();
615 kivi.Order.init_row_handlers();
617 $('#row_table_id').on('sortstop', function(event, ui) {
618 $('#row_table_id thead a img').remove();
619 kivi.Order.renumber_positions();
622 $('#expand_all').on('click', function(event) {
623 event.preventDefault();
624 if ($('#expand_all').data('expanded') == 1) {
625 $('#expand_all').data('expanded', 0);
626 $('#expand_all').attr('src', 'image/expand.svg');
627 $('#expand_all').attr('alt', kivi.t8('Show all details'));
628 $('#expand_all').attr('title', kivi.t8('Show all details'));
629 $('.row_entry').each(function(idx, elt) {
630 kivi.Order.hide_second_row(elt);
633 $('#expand_all').data('expanded', 1);
634 $('#expand_all').attr('src', "image/collapse.svg");
635 $('#expand_all').attr('alt', kivi.t8('Hide all details'));
636 $('#expand_all').attr('title', kivi.t8('Hide all details'));
637 kivi.Order.load_all_second_rows();
638 $('.row_entry').each(function(idx, elt) {
639 kivi.Order.show_second_row(elt);