var cash_envelops = []; var archive_cash_envelops = []; var ch_envelops = []; var archive_ch_envelops = []; var envelop_to_update = null; var members_search_results = []; var selected_member = null; function reset() { $('#cash_envelops').empty(); $('#ch_envelops').empty(); $('#archive_cash_envelops').empty(); $('#archive_ch_envelops').empty(); archive_cash_envelops = []; archive_ch_envelops = []; cash_envelops = []; ch_envelops = []; } function toggle_error_alert() { $('#envelop_cashing_error').toggle(250); } function toggle_success_alert(message) { $('#envelop_cashing_success').find(".success_alert_content") .text(message); $('#envelop_cashing_success').toggle(250); } function toggle_deleted_alert() { $('#envelop_deletion_success').toggle(250); } /** * Get an envelop from the cash or cheque lists dependings on the params * @param {String} type * @param {String} index * @returns */ function get_envelop_from_type_index(type, index) { if (type === "cash") { return cash_envelops[index]; } else { return ch_envelops[index]; } } /** * Define a name for an envelop depending on its type, with or with its type * @param {Object} envelop * @param {String} name_type short | long * @returns */ function get_envelop_name(envelop, name_type = 'short') { let envelop_name = ""; if (envelop.type === "cash") { let split_id = envelop._id.split('_'); let envelop_date = split_id[3].padStart(2, '0') + "/" + split_id[2].padStart(2, '0') + "/" + split_id[1]; envelop_name = `Enveloppe${(name_type === "short") ? "" : " de liquide"} du ${envelop_date}`; } else if (envelop.type == "ch") { envelop_name = `Enveloppe${(name_type === "short") ? "" : " de chèques"} #${envelop.display_id}`; } return envelop_name; } /** * Set the envelops contents on the document (could use a little cleanup someday: don't generate html in js, etc...) * @param {Object} envelop * @param {String} envelop_name * @param {Int} envelop_content_id * @param {Int} envelop_index */ function set_envelop_dom(envelop, envelop_name, envelop_content_id, envelop_index) { var envelops_section =""; if (!envelop.archive) envelops_section = $('#' + envelop.type + '_envelops'); else envelops_section = $('#archive_' + envelop.type + '_envelops'); // Calculate envelop total amount var total_amount = 0; for (partner_id in envelop.envelop_content) { total_amount += envelop.envelop_content[partner_id].amount; } var new_html = '<div class="envelop_section">' + '<div class="flex-container">'; // Allow checking for all cash and first check envelops if ((envelop.type == 'cash' || envelop.type == 'ch' && envelop_index == 0) && !envelop.archive) { new_html += '<button class="accordion w80">' + envelop_name + ' - <i>' + total_amount + '€</i></button>' + '<button class="btn--success archive_button item-fluid" onClick="openModal(\'<h3>Êtes-vous sûr ?</h3>\', function() {archive_envelop(\'' + envelop.type + '\', ' + envelop_index + ');}, \'Encaisser\', false)">Encaisser</button>'; } else if (envelop.archive ===true) { new_html += '<button class="accordion w100">' + envelop_name + ' - <i>' + total_amount + '€'; if (envelop.cashing_date !== undefined) { new_html += ' - Encaissée le ' + envelop.cashing_date; } if (envelop.canceled) { new_html += ' - Enveloppe supprimée'; } new_html += '</i></button>'; } else { new_html += '<button class="accordion w100">' + envelop_name + ' - <i>' + total_amount + '€</i></button>'; } new_html += '</div>' + '<div class="panel panel_' + envelop_content_id + '"><ol class="envelop_content_list" id="' + envelop_content_id + '"></ol></div>' + '</div>'; $(new_html).appendTo(envelops_section); for (node in envelop.envelop_content) { var li_node = document.createElement("LI"); // Create a <li> node var content = envelop.envelop_content[node].partner_name + ' : ' + envelop.envelop_content[node].amount + '€'; if ('payment_id' in envelop.envelop_content[node]) { content += " -- paiement comptabilisé."; } var textnode = document.createTextNode(content); // Create a text node li_node.appendChild(textnode); // Append the text to <li> document.getElementById(envelop_content_id).appendChild(li_node); } let envelop_panel = $(`.panel_${envelop_content_id}`); if (envelop.comments) envelop_panel.append(`<p class="envelop_comment"> <b>Commentaire :</b> ${envelop.comments}</p>`); if (!envelop.archive) { let envelop_panel = $(`.panel_${envelop_content_id}`); envelop_panel.append(`<button class="btn--danger delete_envelop_button item-fluid" id="update_envelop_${envelop.type}_${envelop_index}">Supprimer l'enveloppe</button>`); envelop_panel.append(` <button class="btn--primary update_envelop_button item-fluid" id="update_envelop_${envelop.type}_${envelop_index}" > Modifier </button>`); envelop_panel.append(` <button class="btn--primary add_to_envelop_button item-fluid" id="add_to_envelop_${envelop.type}_${envelop_index}" > Ajouter un paiement ou des parts sociales </button>`); $(".update_envelop_button").off("click"); $(".update_envelop_button").on("click", function() { let el_id = $(this).attr("id") .split("_"); envelop_to_update = { type: el_id[2], index: el_id[3], lines_to_delete: [] }; set_update_envelop_modal(); }); $(".delete_envelop_button").off("click"); $(".delete_envelop_button").on("click", function() { let el_id = $(this).attr("id") .split("_"); let type = el_id[2]; let index = el_id[3]; let envelop = get_envelop_from_type_index(type, index); openModal( "<h3>Supprimer l'enveloppe ?</h3>", function() { archive_canceled_envelop(envelop); }, 'Supprimer' ); }); $(".add_to_envelop_button").off("click"); $(".add_to_envelop_button").on("click", function() { let el_id = $(this).attr("id") .split("_"); envelop_to_update = { type: el_id[el_id.length-2], index: el_id[el_id.length-1] }; let envelop = get_envelop_from_type_index(envelop_to_update.type, envelop_to_update.index); let envelop_name = get_envelop_name(envelop, 'long'); let modal_add_to_envelop = $('#templates #modal_add_to_envelop'); modal_add_to_envelop.find(".envelop_name").text(envelop_name); openModal( modal_add_to_envelop.html(), () => {}, '', false, true, () => { envelop_to_update = null; selected_member = null; modal.find(".btn-modal-ok").show(); } ); // No validation button modal.find(".btn-modal-ok").hide(); modal.find(".add_to_envelop_lines").empty(); // Set action to search for the member modal.find('.search_member_form').submit(function() { let search_str = modal.find('.search_member_input').val(); $.ajax({ url: '/members/search/' + search_str + "?search_type=envelops", dataType : 'json', success: function(data) { members_search_results = data.res; display_possible_members(); }, error: function() { err = { msg: "erreur serveur lors de la recherche de membres", ctx: 'add_payment_to_envelop.search_members' }; report_JS_error(err, 'envelops'); alert("Erreur lors de la recherche de membre, il faut ré-essayer plus tard..."); } }); }); }); } } /** * Given the raw list of envelop documents, generate the cash and cheque lists * @param {Array} envelops */ function set_envelops(envelops) { var cash_index = 0; var ch_index = 0; var archive_cash_index = 0; var archive_ch_index = 0; reset(); for (var i= 0; i < envelops.length; i++) { var envelop = envelops[i].doc; //If the envelop is archived and more than 1 year old we delete it if (envelop.archive && (new Date()-new Date(envelop.creation_date))/ (1000 * 3600 * 24 * 365)>1) { delete_envelop(envelop); } else if (envelop.type == "cash" && envelop.archive != true) { cash_envelops.push(envelop); let envelop_name = get_envelop_name(envelop); let envelop_content_id = 'content_cash_list_' + cash_index; set_envelop_dom(envelop, envelop_name, envelop_content_id, cash_index); cash_index += 1; } else if (envelop.type == "cash" && envelop.archive == true) { archive_cash_envelops.push(envelop); let envelop_name = get_envelop_name(envelop); let envelop_content_id = 'content_archive_cash_list_' + archive_cash_index; set_envelop_dom(envelop, envelop_name, envelop_content_id, archive_cash_index); archive_cash_index += 1; } else if (envelop.type == "ch" && envelop.archive != true) { ch_envelops.push(envelop); let envelop_name = get_envelop_name(envelop); let envelop_content_id = 'content_ch_list_' + ch_index; set_envelop_dom(envelop, envelop_name, envelop_content_id, ch_index); ch_index += 1; } else if (envelop.type == "ch" && envelop.archive == true) { archive_ch_envelops.push(envelop); let envelop_name = get_envelop_name(envelop); let envelop_content_id = 'content_archive_ch_list_' + archive_ch_index; set_envelop_dom(envelop, envelop_name, envelop_content_id, archive_ch_index); archive_ch_index += 1; } } if (cash_index == 0) $('#cash_envelops').html("<p class='txtcenter'>Aucune enveloppe.</p>"); if (ch_index == 0) $('#ch_envelops').html("<p class='txtcenter'>Aucune enveloppe.</p>"); // Set accordions var acc = document.getElementsByClassName("accordion"); for (var j = 0; j < acc.length; j++) { acc[j].addEventListener("click", function() { /* Toggle between adding and removing the "active" class, to highlight the button that controls the panel */ this.classList.toggle("active"); /* Toggle between hiding and showing the active panel */ var panel = this.parentNode.nextElementSibling; // depends on html structure if (panel.style.maxHeight) { panel.style.maxHeight = null; } else { panel.style.maxHeight = panel.scrollHeight + "px"; } }); } } /** * Generate content & set listeners for the modal to update an envelop */ function set_update_envelop_modal() { let envelop = get_envelop_from_type_index(envelop_to_update.type, envelop_to_update.index); let envelop_name = get_envelop_name(envelop, 'long'); let modal_update_envelop = $('#templates #modal_update_envelop'); modal_update_envelop.find(".envelop_name").text(envelop_name); modal_update_envelop.find(".envelop_lines").empty(); let update_line_template = $('#templates #update_envelop_line_template'); let cpt = 1; for (let partner_id in envelop.envelop_content) { let line = envelop.envelop_content[partner_id]; update_line_template.find(".update_envelop_line").attr('id', `update_line_${partner_id}`); update_line_template.find(".line_number").html(`${cpt}. `); update_line_template.find(".line_partner_name").text(line.partner_name); modal_update_envelop.find(".envelop_lines").append(update_line_template.html()); cpt += 1; } openModal( modal_update_envelop.html(), () => { update_envelop_action(); }, 'Mettre à jour', true, true, () => { envelop_to_update = null; } ); // Elements needs to be on the document so value & listeners can be set for (let partner_id in envelop.envelop_content) { let line = envelop.envelop_content[partner_id]; $(`#update_line_${partner_id}`).find('.line_partner_amount') .val(line.amount); } modal.find('.envelop_comments').val((envelop.comments !== undefined) ? envelop.comments : ''); $(".delete_envelop_line_icon").off("click"); $(".delete_envelop_line_icon").on("click", function() { let line_id = $(this).closest(".update_envelop_line") .attr("id") .split("_"); let partner_id = line_id[line_id.length-1]; envelop_to_update.lines_to_delete.push(partner_id); $(this).hide(); $(this).closest(".update_envelop_line") .find(".deleted_line_through") .show(); }); } /** * Update an envelop data with modal data */ function update_envelop_action() { if (is_time_to('update_envelop_action', 1000)) { let envelop = get_envelop_from_type_index(envelop_to_update.type, envelop_to_update.index); // Update lines amounts let amount_inputs = modal.find('.line_partner_amount'); amount_inputs.each(function (i, e) { let line_id = $(e).closest(".update_envelop_line") .attr("id") .split("_"); let partner_id = line_id[line_id.length-1]; envelop.envelop_content[partner_id].amount = parseInt($(e).val()); }); // Delete lines for (let partner_id of envelop_to_update.lines_to_delete) { delete(envelop.envelop_content[partner_id]); } // Envelop comments envelop.comments = modal.find('.envelop_comments').val(); update_envelop(envelop); toggle_success_alert("Enveloppe modifiée !"); } } /** * Update an envelop in couchdb * @param {Object} envelop */ function update_envelop(envelop) { if (is_time_to('update_envelop', 1000)) { dbc.put(envelop, function callback(err, result) { envelop_to_update = null; if (!err && result !== undefined) { get_envelops(); } else { alert("Erreur lors de la mise à jour de l'enveloppe. Si l'erreur persiste contactez un administrateur svp."); console.log(err); } }); } } /** * archive and canceled an envelop from couchdb. * @param {Object} envelop */ function archive_canceled_envelop(envelop) { if (is_time_to('archive_canceled_envelop', 1000)) { envelop.archive = true; envelop.canceled = true; dbc.put(envelop, function callback(err, result) { if (!err && result !== undefined) { toggle_deleted_alert(); get_envelops(); } else { alert("Erreur lors de la suppression de l'enveloppe... Essaye de recharger la page et réessaye."); console.log(err); } }); } } /** * Delete an envelop from couchdb. * @param {Object} envelop */ function delete_envelop(envelop) { if (is_time_to('delete_envelop', 1000)) { envelop._deleted = true; dbc.put(envelop, function callback(err, result) { if (!err && result !== undefined) { get_envelops(); } else { alert("Erreur lors de la suppression de l'enveloppe... Essaye de recharger la page et réessaye."); console.log(err); } }); } } /** * Send the request to save an envelop payments in Odoo. The envelop will be deleted from couchdb. * @param {String} type * @param {String} index */ function archive_envelop(type, index) { if (is_time_to('archive_envelop', 5000)) { $('#envelop_cashing_error').hide(); $('#envelop_cashing_success').hide(); // Loading on openModal(); let envelop = get_envelop_from_type_index(type, index); // Proceed to envelop cashing $.ajax({ type: "POST", url: "/envelops/archive_envelop", headers: { "X-CSRFToken": getCookie("csrftoken") }, dataType: "json", traditional: true, contentType: "application/json; charset=utf-8", data: JSON.stringify(envelop), success: function(response) { closeModal(); var display_success_alert = true; // Handle errors when saving payments var error_payments = response.error_payments; var error_message = ""; for (var i = 0; i < error_payments.length; i++) { if (error_payments[i].done == false) { error_message += "<p>Erreur lors de l'enregistrement du paiement de <b>" + error_payments[i]['partner_name'] + "</b> (id odoo : " + error_payments[i]['partner_id'] + ", valeur à encaisser : " + error_payments[i]['amount'] + "€)."; error_message += "<br/><b>L'opération est à reprendre manuellement dans Odoo pour ce paiement.</b>"; if ('error' in error_payments[i]) { error_message += `<br/>(error: ${error_payments[i]['error']})`; } error_message += "</p>"; } } // If error during envelop deletion var response_envelop = response.envelop; if (response_envelop == "error") { error_message += "<p>Erreur lors de la suppression de l'enveloppe.<br/>"; error_message += "<b>Sauf contre-indication explicite, les paiements ont bien été enregistrés.</b><br/>"; error_message += "Les paiements déjà comptabilisés ne le seront pas à nouveau, vous pouvez ré-essayer. Si l'erreur persiste, l'enveloppe devra être supprimée manuellement.</p>"; display_success_alert = false; } if (error_message !== "") { $('#error_alert_txt').html(error_message); toggle_error_alert(); } if (display_success_alert) { toggle_success_alert("Enveloppe encaissée !"); } }, error: function() { closeModal(); alert('Erreur serveur. Merci de ne pas ré-encaisser l\'enveloppe qui a causé l\'erreur.'); } }); } else { alert("Par sécurité, il faut attendre 5s entre l'encaissement de deux enveloppes."); } } /** * Get all the envelops from couchdb */ function get_envelops() { dbc.allDocs({ include_docs: true, attachments: true }).then(function (result) { set_envelops(result.rows); }) .catch(function (err) { alert('Erreur lors de la récupération des enveloppes.'); console.log(err); }); } /** * Display the members from the search result in the "add payments to envelop" modal */ function display_possible_members() { modal.find('.search_member_results_area').show(); modal.find('.search_member_results').empty(); if (members_search_results.length > 0) { $(".search_results_text").show(); for (member of members_search_results) { // Display results (possible members) as buttons var member_button = '<button class="btn--success btn_possible_member" member_id="' + member.id + '">' + member.barcode_base + ' - ' + member.name + '</button>'; $('.search_member_results').append(member_button); } // Set action on member button click $('.btn_possible_member').on('click', function() { const mid = $(this).attr('member_id'); selected_member = members_search_results.find(m => m.id == mid); members_search_results = []; modal.find('.search_member_input').val(''); modal.find('.search_member_results').empty(); modal.find('.search_member_results_area').hide(); // Adding line for this member in modal... display_line_add_payment(); }); } else { $(".search_results_text").hide(); $('.search_member_results').html(`<p> <i>Aucun résultat ! Vérifiez votre recherche...</i> </p>`); } } /** * Display a line for adding a member's payment in the "add payments to envelop" modal */ function display_line_add_payment() { let envelop = get_envelop_from_type_index(envelop_to_update.type, envelop_to_update.index); // Block adding payment if member is already in the envelop for (let env_partner_id in envelop.envelop_content) { if (env_partner_id == selected_member.id) { alert("Ce membre est déjà dans l'enveloppe, impossible de lui rajouter un paiement.\nVous pouvez modifier le montant de son paiement dans la fenêtre de modification de l'enveloppe."); return -1; } } modal.find('.search_member_area').hide(); let modal_line = $('#templates #add_to_envelop_line_template'); modal_line.find(".line_partner_name").text(selected_member.name); modal.find(".add_to_envelop_lines").append(modal_line.html()); modal.find(".add_to_envelop_lines_area").show(); // Add payment button $('.add_payment_button').off('click'); $('.add_payment_button').on('click', function() { let amount = parseInt(modal.find(".line_partner_amount").val(), 10); if (isNaN(amount)) { modal.find(".line_partner_amount_error").show(); } else { modal.find(".line_partner_amount_error").hide(); let modal_confirm_add_payment = $('#templates #modal_confirm_add_payment'); modal_confirm_add_payment.find(".amount").text(amount); modal_confirm_add_payment.find(".member").text(selected_member.name); modal_confirm_add_payment.find(".envelop").text(get_envelop_name(envelop, 'long')); openModal( modal_confirm_add_payment.html(), () => { add_payment_to_envelop(amount, envelop); }, "Confirmer" ); modal.find(".btn-modal-ok").show(); } }); // Add shares button $('.add_shares_button').off('click'); $('.add_shares_button').on('click', function() { let amount = parseInt(modal.find(".line_partner_amount").val(), 10); if (isNaN(amount)) { modal.find(".line_partner_amount_error").show(); } else { modal.find(".line_partner_amount_error").hide(); let modal_confirm_add_shares = $('#templates #modal_confirm_add_shares'); modal_confirm_add_shares.find(".amount").text(amount); modal_confirm_add_shares.find(".member").text(selected_member.name); modal_confirm_add_shares.find(".envelop").text(get_envelop_name(envelop, 'long')); openModal( modal_confirm_add_shares.html(), () => { add_shares_to_member(amount, envelop); }, "Confirmer", false ); modal.find(".btn-modal-ok").show(); } }); return null; } /** * Add a payment in an envelop & save in couchdb * @param {Int} amount * @param {Object} envelop * @param {Int} invoice_id * @param {String} message */ function add_payment_to_envelop(amount, envelop, invoice_id=null, message="Paiement ajouté !") { if (is_time_to('add_payment_to_envelop', 1000)) { envelop.envelop_content[selected_member.id] = { partner_name: selected_member.name, amount: amount }; if (invoice_id != null) { envelop.envelop_content[selected_member.id].invoice_id = invoice_id; } update_envelop(envelop); toggle_success_alert(message); envelop_to_update = null; selected_member = null; get_envelops(); } } /** * Send request to add shares & then add payment * @param {Int} amount * @param {Object} envelop */ function add_shares_to_member(amount, envelop) { if (is_time_to('add_shares_to_member', 1000)) { openModal(); data = { partner_id: selected_member.id, amount: amount }; $.ajax({ type: "POST", url: "/members/add_shares_to_member", headers: { "X-CSRFToken": getCookie("csrftoken") }, dataType: "json", traditional: true, contentType: "application/json; charset=utf-8", data: JSON.stringify(data), success: function(response) { closeModal(); invoice_id = response[0]; add_payment_to_envelop(amount, envelop, invoice_id, "Parts sociales ajoutées !"); }, error: function() { closeModal(); alert('Un erreur est survenue lors de l\'ajout de parts sociales.'); } }); } } $(document).ready(function() { if (typeof must_identify == "undefined" || coop_is_connected()) { get_envelops(); // Hande change in couc db sync.on('change', function (info) { // handle change if (info.direction == 'pull') { get_envelops(); } }).on('error', function (err) { // handle error console.log('erreur sync'); console.log(err); }); } });