1 namespace('kivi.Order', function(ns) {
2 ns.check_cv = function() {
3 if ($('#type').val() == 'sales_order') {
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_and_delivery_order = 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_and_delivery_order' });
55 $.post("controller.pl", data, kivi.eval_json_result);
58 ns.save_and_invoice = 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_invoice' });
65 $.post("controller.pl", data, kivi.eval_json_result);
68 ns.delete_order = function() {
69 var data = $('#order_form').serializeArray();
70 data.push({ name: 'action', value: 'Order/delete' });
72 $.post("controller.pl", data, kivi.eval_json_result);
75 ns.show_print_options = function() {
76 if (!ns.check_cv()) return;
81 title: kivi.t8('Print options'),
88 ns.print = function() {
89 $('#print_options').dialog('close');
91 var data = $('#order_form').serializeArray();
92 data = data.concat($('#print_options_form').serializeArray());
93 data.push({ name: 'action', value: 'Order/print' });
95 $.post("controller.pl", data, kivi.eval_json_result);
98 ns.download_pdf = function(pdf_filename, key) {
100 data.push({ name: 'action', value: 'Order/download_pdf' });
101 data.push({ name: 'type', value: $('#type').val() });
102 data.push({ name: 'pdf_filename', value: pdf_filename });
103 data.push({ name: 'key', value: key });
104 $.download("controller.pl", data);
107 ns.email = function() {
108 if (!ns.check_cv()) return;
109 var data = $('#order_form').serializeArray();
110 data.push({ name: 'action', value: 'Order/show_email_dialog' });
112 $.post("controller.pl", data, kivi.eval_json_result);
117 ns.setup_send_email_dialog = function() {
118 kivi.SalesPurchase.show_all_print_options_elements();
119 kivi.SalesPurchase.show_print_options_elements([ 'sendmode', 'media', 'copies', 'remove_draft' ], false);
121 $('#print_options_form table').first().remove().appendTo('#email_form_print_options');
123 var to_focus = $('#email_form_to').val() === '' ? 'to' : 'subject';
124 $('#email_form_' + to_focus).focus();
127 ns.finish_send_email_dialog = function() {
128 kivi.SalesPurchase.show_all_print_options_elements();
130 $('#email_form_print_options table').first().remove().prependTo('#print_options_form');
134 ns.show_email_dialog = function(html) {
135 var id = 'send_email_dialog';
136 var dialog_params = {
140 title: kivi.t8('Send email'),
142 beforeClose: kivi.Order.finish_send_email_dialog,
143 close: function(event, ui) {
144 email_dialog.remove();
148 $('#' + id).remove();
150 email_dialog = $('<div style="display:none" id="' + id + '"></div>').appendTo('body');
151 email_dialog.html(html);
152 email_dialog.dialog(dialog_params);
154 kivi.Order.setup_send_email_dialog();
156 $('.cancel').click(ns.close_email_dialog);
161 ns.send_email = function() {
162 var data = $('#order_form').serializeArray();
163 data = data.concat($('[name^="email_form."]').serializeArray());
164 data = data.concat($('[name^="print_options."]').serializeArray());
165 data.push({ name: 'action', value: 'Order/send_email' });
166 $.post("controller.pl", data, kivi.eval_json_result);
169 ns.close_email_dialog = function() {
170 email_dialog.dialog("close");
173 ns.reload_cv_dependant_selections = function() {
174 var data = $('#order_form').serializeArray();
175 data.push({ name: 'action', value: 'Order/customer_vendor_changed' });
177 $.post("controller.pl", data, kivi.eval_json_result);
180 ns.reformat_number = function(event) {
181 $(event.target).val(kivi.format_amount(kivi.parse_amount($(event.target).val()), -2));
184 ns.recalc_amounts_and_taxes = function() {
185 var data = $('#order_form').serializeArray();
186 data.push({ name: 'action', value: 'Order/recalc_amounts_and_taxes' });
188 $.post("controller.pl", data, kivi.eval_json_result);
191 ns.unit_change = function(event) {
192 var row = $(event.target).parents("tbody").first();
193 var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
194 var sellprice_dom = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
195 var select_elt = $(row).find('[name="order.orderitems[].unit"]');
197 var oldval = $(select_elt).data('oldval');
198 $(select_elt).data('oldval', $(select_elt).val());
200 var data = $('#order_form').serializeArray();
201 data.push({ name: 'action', value: 'Order/unit_changed' });
202 data.push({ name: 'item_id', value: item_id_dom.val() });
203 data.push({ name: 'old_unit', value: oldval });
204 data.push({ name: 'sellprice_dom_id', value: sellprice_dom.attr('id') });
206 $.post("controller.pl", data, kivi.eval_json_result);
209 ns.update_sellprice = function(item_id, price_str) {
210 var row = $('#item_' + item_id).parents("tbody").first();
211 var price_elt = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
212 var html_elt = $(row).find('[name="sellprice_text"]');
213 price_elt.val(price_str);
214 html_elt.html(price_str);
217 ns.load_second_row = function(row) {
218 var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
219 var div_elt = $(row).find('[name="second_row"]');
221 if ($(div_elt).data('loaded') == 1) {
224 var data = $('#order_form').serializeArray();
225 data.push({ name: 'action', value: 'Order/load_second_rows' });
226 data.push({ name: 'item_ids[]', value: item_id_dom.val() });
228 $.post("controller.pl", data, kivi.eval_json_result);
231 ns.load_all_second_rows = function() {
232 var rows = $('.row_entry').filter(function(idx, elt) {
233 return $(elt).find('[name="second_row"]').data('loaded') != 1;
236 var item_ids = $.map(rows, function(elt) {
237 var item_id = $(elt).find('[name="orderitem_ids[+]"]').val();
238 return { name: 'item_ids[]', value: item_id };
241 if (item_ids.length == 0) {
245 var data = $('#order_form').serializeArray();
246 data.push({ name: 'action', value: 'Order/load_second_rows' });
247 data = data.concat(item_ids);
249 $.post("controller.pl", data, kivi.eval_json_result);
252 ns.hide_second_row = function(row) {
253 $(row).children().not(':first').hide();
254 $(row).data('expanded', 0);
255 var elt = $(row).find('.expand');
256 elt.attr('src', "image/expand.svg");
257 elt.attr('alt', kivi.t8('Show details'));
258 elt.attr('title', kivi.t8('Show details'));
261 ns.show_second_row = function(row) {
262 $(row).children().not(':first').show();
263 $(row).data('expanded', 1);
264 var elt = $(row).find('.expand');
265 elt.attr('src', "image/collapse.svg");
266 elt.attr('alt', kivi.t8('Hide details'));
267 elt.attr('title', kivi.t8('Hide details'));
270 ns.toggle_second_row = function(row) {
271 if ($(row).data('expanded') == 1) {
272 ns.hide_second_row(row);
274 ns.show_second_row(row);
278 ns.init_row_handlers = function() {
279 kivi.run_once_for('.recalc', 'on_change_recalc', function(elt) {
280 $(elt).change(ns.recalc_amounts_and_taxes);
283 kivi.run_once_for('.reformat_number', 'on_change_reformat', function(elt) {
284 $(elt).change(ns.reformat_number);
287 kivi.run_once_for('.unitselect', 'on_change_unit_with_oldval', function(elt) {
288 $(elt).data('oldval', $(elt).val());
289 $(elt).change(ns.unit_change);
292 kivi.run_once_for('.row_entry', 'on_kbd_click_show_hide', function(elt) {
293 $(elt).keydown(function(event) {
294 if(event.keyCode == 40 && event.shiftKey === true) {
296 event.preventDefault();
297 var row = $(event.target).parents(".row_entry").first();
298 ns.load_second_row(row);
299 ns.show_second_row(row);
302 if(event.keyCode == 38 && event.shiftKey === true) {
304 event.preventDefault();
305 var row = $(event.target).parents(".row_entry").first();
306 ns.hide_second_row(row);
312 kivi.run_once_for('.expand', 'expand_second_row', function(elt) {
313 $(elt).click(function(event) {
314 event.preventDefault();
315 var row = $(event.target).parents(".row_entry").first();
316 ns.load_second_row(row);
317 ns.toggle_second_row(row);
324 ns.redisplay_line_values = function(is_sales, data) {
325 $('.row_entry').each(function(idx, elt) {
326 $(elt).find('[name="linetotal"]').html(data[idx][0]);
327 if (is_sales && $(elt).find('[name="second_row"]').data('loaded') == 1) {
328 var mt = data[idx][1];
329 var mp = data[idx][2];
331 if (mt[0] === '-') h += ' class="plus0"';
332 h += '>' + mt + ' ' + mp + '%';
334 $(elt).find('[name="linemargin"]').html(h);
339 ns.renumber_positions = function() {
340 $('.row_entry [name="position"]').each(function(idx, elt) {
345 ns.reorder_items = function(order_by) {
346 var dir = $('#' + order_by + '_header_id a img').attr("data-sort-dir");
347 $('#row_table_id thead a img').remove();
352 src = "image/up.png";
355 src = "image/down.png";
358 $('#' + order_by + '_header_id a').append('<img border=0 data-sort-dir=' + dir + ' src=' + src + ' alt="' + kivi.t8('sort items') + '">');
360 var data = $('#order_form').serializeArray();
361 data.push({ name: 'action', value: 'Order/reorder_items' });
362 data.push({ name: 'order_by', value: order_by });
363 data.push({ name: 'sort_dir', value: dir });
365 $.post("controller.pl", data, kivi.eval_json_result);
368 ns.redisplay_items = function(data) {
369 var old_rows = $('.row_entry').detach();
371 $(data).each(function(idx, elt) {
372 new_rows.push(old_rows[elt.old_pos - 1]);
374 $(new_rows).appendTo($('#row_table_id'));
375 ns.renumber_positions();
378 ns.add_item = function() {
379 if ($('#add_item_parts_id').val() === '') return;
380 if (!ns.check_cv()) return;
382 $('#row_table_id thead a img').remove();
384 var data = $('#order_form').serializeArray();
385 data.push({ name: 'action', value: 'Order/add_item' });
387 $.post("controller.pl", data, kivi.eval_json_result);
390 ns.show_multi_items_dialog = function() {
391 if (!ns.check_cv()) return;
393 $('#row_table_id thead a img').remove();
396 url: 'controller.pl?action=Order/show_multi_items_dialog',
397 data: { type: $('#type').val(),
398 callback: 'Order/add_multi_items',
399 callback_data_id: 'order_form' },
400 id: 'jq_multi_items_dialog',
402 title: kivi.t8('Add multiple items'),
410 ns.close_multi_items_dialog = function() {
411 $('#jq_multi_items_dialog').dialog('close');
414 ns.delete_order_item_row = function(clicked) {
415 var row = $(clicked).parents("tbody").first();
418 ns.renumber_positions();
419 ns.recalc_amounts_and_taxes();
422 ns.row_table_scroll_down = function() {
423 $('#row_table_scroll_id').scrollTop($('#row_table_scroll_id')[0].scrollHeight);
426 ns.show_longdescription_dialog = function(clicked) {
427 var row = $(clicked).parents("tbody").first();
428 var position = $(row).find('[name="position"]').html();
429 var partnumber = $(row).find('[name="partnumber"]').html();
430 var description_elt = $(row).find('[name="order.orderitems[].description"]');
431 var description = description_elt.val();
432 var longdescription_elt = $(row).find('[name="order.orderitems[].longdescription"]');
435 if (!longdescription_elt.length) {
437 data.push({ name: 'action', value: 'Order/get_item_longdescription' });
438 data.push({ name: 'type', value: $('#type').val() });
439 data.push({ name: 'item_id', value: $(row).find('[name="order.orderitems[+].id"]').val() });
440 data.push({ name: 'parts_id', value: $(row).find('[name="order.orderitems[].parts_id"]').val() });
442 url: 'controller.pl',
447 success: function(val){
448 longdescription = val;
452 longdescription = longdescription_elt.val();
455 var params = { runningnumber: position,
456 partnumber: partnumber,
457 description: description,
458 default_longdescription: longdescription,
459 set_function: function(val){
460 longdescription_elt.remove();
461 $('<input type="hidden" name="order.orderitems[].longdescription">').insertAfter(description_elt).val(val);
465 kivi.SalesPurchase.edit_longdescription_with_params(params);
468 ns.price_chooser_item_row = function(clicked) {
469 var row = $(clicked).parents("tbody").first();
470 var item_id_dom = $(row).find('[name="orderitem_ids[+]"]');
472 var data = $('#order_form').serializeArray();
473 data.push({ name: 'action', value: 'Order/price_popup' });
474 data.push({ name: 'item_id', value: item_id_dom.val() });
476 $.post("controller.pl", data, kivi.eval_json_result);
479 ns.update_price_source = function(item_id, source, descr, price_str, price_editable) {
480 var row = $('#item_' + item_id).parents("tbody").first();
481 var source_elt = $(row).find('[name="order.orderitems[].active_price_source"]');
482 var button_elt = $(row).find('[name="price_chooser_button"]');
484 button_elt.val(button_elt.val().replace(/.*\|/, descr + " |"));
485 source_elt.val(source);
487 var editable_div_elt = $(row).find('[name="editable_price"]');
488 var not_editable_div_elt = $(row).find('[name="not_editable_price"]');
489 if (price_editable == 1 && source === '') {
491 $(editable_div_elt).show();
492 $(not_editable_div_elt).hide();
493 $(editable_div_elt).find(':input').prop("disabled", false);
494 $(not_editable_div_elt).find(':input').prop("disabled", true);
497 $(editable_div_elt).hide();
498 $(not_editable_div_elt).show();
499 $(editable_div_elt).find(':input').prop("disabled", true);
500 $(not_editable_div_elt).find(':input').prop("disabled", false);
504 var price_elt = $(row).find('[name="order.orderitems[].sellprice_as_number"]');
505 var html_elt = $(row).find('[name="sellprice_text"]');
506 price_elt.val(price_str);
507 html_elt.html(price_str);
508 ns.recalc_amounts_and_taxes();
511 kivi.io.close_dialog();
514 ns.update_discount_source = function(item_id, source, descr, discount_str, price_editable) {
515 var row = $('#item_' + item_id).parents("tbody").first();
516 var source_elt = $(row).find('[name="order.orderitems[].active_discount_source"]');
517 var button_elt = $(row).find('[name="price_chooser_button"]');
519 button_elt.val(button_elt.val().replace(/\|.*/, "| " + descr));
520 source_elt.val(source);
522 var editable_div_elt = $(row).find('[name="editable_discount"]');
523 var not_editable_div_elt = $(row).find('[name="not_editable_discount"]');
524 if (price_editable == 1 && source === '') {
526 $(editable_div_elt).show();
527 $(not_editable_div_elt).hide();
528 $(editable_div_elt).find(':input').prop("disabled", false);
529 $(not_editable_div_elt).find(':input').prop("disabled", true);
532 $(editable_div_elt).hide();
533 $(not_editable_div_elt).show();
534 $(editable_div_elt).find(':input').prop("disabled", true);
535 $(not_editable_div_elt).find(':input').prop("disabled", false);
539 var discount_elt = $(row).find('[name="order.orderitems[].discount_as_percent"]');
540 var html_elt = $(row).find('[name="discount_text"]');
541 discount_elt.val(discount_str);
542 html_elt.html(discount_str);
543 ns.recalc_amounts_and_taxes();
546 kivi.io.close_dialog();
549 ns.show_periodic_invoices_config_dialog = function() {
550 if ($('#type').val() !== 'sales_order') return;
553 url: 'controller.pl?action=Order/show_periodic_invoices_config_dialog',
554 data: { type : $('#type').val(),
556 config : $('#order_periodic_invoices_config').val(),
557 customer_id: $('#order_customer_id').val(),
558 transdate : $('#order_transdate').val(),
559 language_id: $('#language_id').val()
561 id: 'jq_periodic_invoices_config_dialog',
562 load: kivi.reinit_widgets,
564 title: kivi.t8('Edit the configuration for periodic invoices'),
572 ns.close_periodic_invoices_config_dialog = function() {
573 $('#jq_periodic_invoices_config_dialog').dialog('close');
576 ns.assign_periodic_invoices_config = function() {
577 var data = $('[name="Form"]').serializeArray();
578 data.push({ name: 'type', value: $('#type').val() });
579 data.push({ name: 'action', value: 'Order/assign_periodic_invoices_config' });
580 $.post("controller.pl", data, kivi.eval_json_result);
583 ns.check_save_active_periodic_invoices = function() {
584 var type = $('#type').val();
585 if (type !== 'sales_order') return true;
589 url: 'controller.pl',
590 data: { action: 'Order/get_has_active_periodic_invoices',
593 config: $('#order_periodic_invoices_config').val(),
598 success: function(val){
604 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?'));
613 if ($('#type').val() == 'sales_order') {
614 $('#order_customer_id').change(kivi.Order.reload_cv_dependant_selections);
616 $('#order_vendor_id').change(kivi.Order.reload_cv_dependant_selections);
619 if ($('#type').val() == 'sales_order') {
620 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_sellprice_as_number').val(kivi.format_amount(o.sellprice, -2)) });
622 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_sellprice_as_number').val(kivi.format_amount(o.lastcost, -2)) });
624 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_description').val(o.description) });
625 $('#add_item_parts_id').on('set_item:PartPicker', function(e,o) { $('#add_item_unit').val(o.unit) });
627 $('.add_item_input').keydown(function(event) {
628 if(event.keyCode == 13) {
629 event.preventDefault();
630 kivi.Order.add_item();
635 kivi.Order.init_row_handlers();
637 $('#row_table_id').on('sortstop', function(event, ui) {
638 $('#row_table_id thead a img').remove();
639 kivi.Order.renumber_positions();
642 $('#expand_all').on('click', function(event) {
643 event.preventDefault();
644 if ($('#expand_all').data('expanded') == 1) {
645 $('#expand_all').data('expanded', 0);
646 $('#expand_all').attr('src', 'image/expand.svg');
647 $('#expand_all').attr('alt', kivi.t8('Show all details'));
648 $('#expand_all').attr('title', kivi.t8('Show all details'));
649 $('.row_entry').each(function(idx, elt) {
650 kivi.Order.hide_second_row(elt);
653 $('#expand_all').data('expanded', 1);
654 $('#expand_all').attr('src', "image/collapse.svg");
655 $('#expand_all').attr('alt', kivi.t8('Hide all details'));
656 $('#expand_all').attr('title', kivi.t8('Hide all details'));
657 kivi.Order.load_all_second_rows();
658 $('.row_entry').each(function(idx, elt) {
659 kivi.Order.show_second_row(elt);