Commit c325b191 by Damien Moulard

members admin: remove makeups to members

parent 1960692a
Pipeline #1337 failed with stage
in 1 minute 24 seconds
......@@ -214,4 +214,32 @@ def create_envelops(request):
response = JsonResponse(res, safe=False)
else:
response = JsonResponse(res, status=403)
return response
\ No newline at end of file
return response
# # # ADMIN / BDM # # #
def admin(request):
""" Administration des membres """
template = loader.get_template('members/admin/index.html')
context = {'title': 'BDM',
'module': 'Membres'}
return HttpResponse(template.render(context, request))
def get_makeups_members(request):
""" Récupération des membres qui doivent faire des rattrapages """
res = CagetteMembers.get_makeups_members()
return JsonResponse({ 'res' : res })
def update_members_makeups(request):
""" Décrémente les rattrapages des membres passés dans la requête """
res = {}
is_connected_user = CagetteUser.are_credentials_ok(request)
if is_connected_user is True:
members_data = json.loads(request.body.decode())
res["res"] = CagetteMembers.update_members_makeups(members_data)
response = JsonResponse(res)
else:
res["message"] = "Unauthorized"
response = JsonResponse(res, status=403)
return response
......@@ -1015,7 +1015,28 @@ class CagetteMembers(models.Model):
res['error'] = str(e)
return res
@staticmethod
def get_makeups_members():
api = OdooAPI()
cond = [['makeups_to_do','>', 0]]
fields = ['id', 'name', 'makeups_to_do']
res = api.search_read('res.partner', cond, fields)
return res
@staticmethod
def update_members_makeups(members_data):
api = OdooAPI()
res = []
for member_data in members_data:
member_id = int(member_data["member_id"])
f = { 'makeups_to_do': int(member_data["target_makeups_nb"]) }
res_item = api.update('res.partner', [member_id], f)
res.append({
'mid': member_id,
'update': res_item
})
return res
class CagetteServices(models.Model):
"""Class to handle cagette Odoo services."""
......
.page_body{
position: relative;
}
.login_area {
position: absolute;
top: 0;
left: 0;
right: 0;
}
.tabs {
margin-top: 1em;
margin-bottom: 1em;
overflow: hidden;
}
.tabs .tab {
background-color: #f1f1f1;
border: 1px solid #ccc;
outline: none;
cursor: pointer;
padding: 14px 16px;
transition: 0.3s;
}
.tabs .tab:hover {
background-color: #ccc;
}
.tabs .active {
background-color: transparent;
border: 1px solid #ccc;
border-width: 1px 0 0 0;
}
.tabs .active:hover {
background-color: white;
}
.tab_content {
animation: fadeEffect 1s; /* Fading effect takes 1 second */
}
/* Go from zero to full opacity */
@keyframes fadeEffect {
from {opacity: 0;}
to {opacity: 1;}
}
#tab_makeups_content {
padding: 2rem 0;
}
.table_area {
margin-top: 20px;
}
.decrement_makeup {
padding: 0.4rem 1.25rem;
margin-left: 10px;
}
\ No newline at end of file
var makeups_members_table = null,
makeups_members = null;
function switch_active_tab() {
// Set tabs
$('.tab').removeClass('active');
$(this).addClass('active');
// Tabs content
$('.tab_content').hide();
let tab = $(this).attr('id');
if (tab == 'tab_settings') {
$('#tab_settings_content').show();
} else {
// Default
$('#tab_makeups_content').show();
}
load_tab_data();
}
function load_tab_data() {
let current_tab = $('.tab .active').attr('id');
if (current_tab === 'tab_makeups') {
load_makeups_members();
}
}
function load_makeups_members() {
$.ajax({
type: 'GET',
url: "/members/get_makeups_members",
dataType:"json",
traditional: true,
contentType: "application/json; charset=utf-8",
success: function(data) {
makeups_members = data.res;
display_makeups_members();
},
error: function(data) {
err = {msg: "erreur serveur lors de la récupération des membres avec rattrapage", ctx: 'load_makeups_members'};
if (typeof data.responseJSON != 'undefined' && typeof data.responseJSON.error != 'undefined') {
err.msg += ' : ' + data.responseJSON.error;
}
report_JS_error(err, 'orders');
closeModal();
alert('Erreur serveur lors de la récupération des membres avec rattrapage. Ré-essayez plus tard.');
}
});
}
function display_makeups_members() {
if (makeups_members_table) {
$('#makeups_members_table').off();
makeups_members_table.clear().destroy();
$('#makeups_members_table').empty();
}
// Remove members with 0 makeups to do
ids_to_remove = []
for (of in makeups_members) {
if (makeups_members[i].makeups_to_do == 0) {
ids_to_remove.push(makeups_members[i].id)
}
}
makeups_members = makeups_members.filter(m => !ids_to_remove.includes(m.id))
// TODO : select multiple and grouped action
makeups_members_table = $('#makeups_members_table').DataTable({
data: makeups_members,
columns: [
{
data: "id",
title: '',
className: "dt-body-center",
orderable: false,
render: function (data) {
return `<input type="checkbox" class="select_member_cb" id="select_member_${data}" value="${data}">`;
},
width: "3%"
},
{
data: "name",
title: "Nom",
},
{
data: "makeups_to_do",
title: "Nb rattrapages",
className: "dt-body-center",
width: "10%",
render: function (data, type, full) {
return `<b>${data}</b>
<button class="decrement_makeup btn--primary" id="decrement_member_${full.id}">
<i class="fas fa-arrow-down"></i>
</button>`;
},
}
],
aLengthMenu: [
[
25,
50,
-1
],
[
25,
50,
"Tout"
]
],
iDisplayLength: -1,
language: {url : '/static/js/datatables/french.json'},
});
$('#makeups_members_table').on('click', 'tbody td .decrement_makeup', function () {
const button_id = $(this).prop('id').split('_');
const member_id = button_id[button_id.length - 1];
const member = makeups_members.find(m => m.id == member_id);
openModal(
`Enlever un rattrapage à ${member.name} ?`,
() => {
decrement_makeups([member_id]);
},
"Confirmer",
false
)
});
}
function decrement_makeups(member_ids) {
openModal();
data = []
for (mid of member_ids) {
member_index = makeups_members.findIndex(m => m.id == mid);
makeups_members[member_index].makeups_to_do -= 1;
data.push({
member_id: mid,
target_makeups_nb: makeups_members[member_index].makeups_to_do
})
}
$.ajax({
type: 'POST',
url: "/members/update_members_makeups",
data: JSON.stringify(data),
dataType:"json",
traditional: true,
contentType: "application/json; charset=utf-8",
success: function(data) {
display_makeups_members();
closeModal()
},
error: function(data) {
err = {msg: "erreur serveur pour décrémenter les rattrapages", ctx: 'load_makeups_members'};
if (typeof data.responseJSON != 'undefined' && typeof data.responseJSON.error != 'undefined') {
err.msg += ' : ' + data.responseJSON.error;
}
report_JS_error(err, 'orders');
closeModal();
alert('Erreur serveur lors de la récupération des membres avec rattrapage. Ré-essayez plus tard.');
}
});
}
$(document).ready(function() {
$.ajaxSetup({ headers: { "X-CSRFToken": getCookie('csrftoken') } });
load_makeups_members();
$(".tabs .tab").on('click', switch_active_tab);
});
......@@ -49,4 +49,8 @@ urlpatterns = [
url(r'^easy_validate_shift_presence$', views.easy_validate_shift_presence),
# conso / groupe recherche / socio
url(r'^panel_get_purchases$', views.panel_get_purchases),
# BDM - members admin
url(r'^admin$', admin.admin),
url(r'^get_makeups_members$', admin.get_makeups_members),
url(r'^update_members_makeups$', admin.update_members_makeups),
]
{% extends "base.html" %}
{% load static %}
{% block additionnal_css %}
<link rel="stylesheet" href="{% static 'css/datatables/datatables.min.css' %}">
<link rel="stylesheet" href="{% static 'css/members_admin.css' %}">
<link rel="stylesheet" href="{% static 'jquery-ui-1.12.1/jquery-ui.min.css' %}">
{% endblock %}
{% block additionnal_scripts %}
<script type="text/javascript" src="{% static 'jquery-ui-1.12.1/jquery-ui.min.js' %}"></script>
<script type="text/javascript" src="{% static 'js/datatables/datatables.min.js' %}"></script>
{% endblock %}
{% block content %}
<div class="page_body">
<div class="login_area">
{% include "common/conn_admin.html" %}
</div>
<div class="header txtcenter">
<h1>Bureau des membres</h1>
</div>
<section class="tabs autogrid">
<div class="button tab active" id="tab_makeups"><h5>Rattrapages</h5></div>
<div class="button tab" id="tab_settings"><h5>Réglages</h5></div>
</section>
<div id="tab_makeups_content" class="tab_content">
<h3>Liste des membres devant effectuer un rattrapage</h3>
<div class="table_area">
<table id="makeups_members_table" class="display" cellspacing="0" width="100%"></table>
</div>
</div>
<div id="tab_settings_content" class="tab_content" style="display:none;">
...
</div>
<div id="templates" style="display:none;"></div>
</div>
<script src='{% static "js/all_common.js" %}?v='></script>
<script src='{% static "js/members_admin.js" %}?v='></script>
{% endblock %}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment