Commit 52f4db76 by Damien Moulard

interface to remove members shift registrations

parent e6577d4f
Pipeline #1837 passed with stage
in 1 minute 28 seconds
...@@ -4,6 +4,7 @@ from outils.for_view_imports import * ...@@ -4,6 +4,7 @@ from outils.for_view_imports import *
from members.models import CagetteUser from members.models import CagetteUser
from members.models import CagetteMembers from members.models import CagetteMembers
from members.models import CagetteMember from members.models import CagetteMember
from shifts.models import CagetteShift
from outils.common import MConfig from outils.common import MConfig
...@@ -318,6 +319,13 @@ def manage_makeups(request): ...@@ -318,6 +319,13 @@ def manage_makeups(request):
'module': 'Membres'} 'module': 'Membres'}
return HttpResponse(template.render(context, request)) return HttpResponse(template.render(context, request))
def manage_shift_registrations(request):
""" Administration des services des membres """
template = loader.get_template('members/admin/manage_shift_registrations.html')
context = {'title': 'BDM - Services',
'module': 'Membres'}
return HttpResponse(template.render(context, request))
def get_makeups_members(request): def get_makeups_members(request):
""" Récupération des membres qui doivent faire des rattrapages """ """ Récupération des membres qui doivent faire des rattrapages """
res = CagetteMembers.get_makeups_members() res = CagetteMembers.get_makeups_members()
...@@ -370,3 +378,24 @@ def update_members_makeups(request): ...@@ -370,3 +378,24 @@ def update_members_makeups(request):
res["message"] = "Unauthorized" res["message"] = "Unauthorized"
response = JsonResponse(res, status=403) response = JsonResponse(res, status=403)
return response return response
def delete_shift_registration(request):
""" From BDM admin, delete (cancel) a member shift registration """
res = {}
is_connected_user = CagetteUser.are_credentials_ok(request)
if is_connected_user is True:
data = json.loads(request.body.decode())
shift_registration_id = int(data["shift_registration_id"])
member_id = int(data["member_id"])
m = CagetteShift()
res["res"] = m.cancel_shift([shift_registration_id])
# Note: 'upcoming_registration_count' in res.partner won't change because the _compute method
# in odoo counts canceled shift registrations.
response = JsonResponse(res, safe=False)
else:
res["message"] = "Unauthorized"
response = JsonResponse(res, status=403)
return response
\ No newline at end of file
.header {
margin: 1rem 0;
}
.login_area {
position: absolute;
display: block;
top: 5px;
right: 5px;
}
#back_to_admin_index {
position: absolute;
top: 5px;
left: 5px;
}
#table_top_area {
display: none;
width: 90%;
margin: 35px auto 0 auto;
text-align: center;
}
.table_area {
margin: 0 auto;
width: 90%;
display: flex;
justify-content: center;
}
.delete_shift_registration {
color: #d9534f;
cursor: pointer;
}
#member_shifts_table_filter {
padding-top: 0.755em;
}
/* Search membres area */
#search_member_area {
margin-top: 30px;
display: flex;
flex-direction: column;
align-items: center;
}
#search_member_form_area {
display:flex;
align-items: center;
}
#search_member_form {
margin-left: 10px;
}
.search_member_results_area {
margin-top: 15px;
display: flex;
align-items: center;
}
.search_results_text {
min-width: 150px;
}
.search_member_results {
display: flex;
flex-wrap: wrap;
}
.btn_possible_member {
margin: 0.5rem 1rem;
}
\ No newline at end of file
...@@ -11,8 +11,8 @@ $(document).ready(function() { ...@@ -11,8 +11,8 @@ $(document).ready(function() {
window.location.assign(location + "/manage_makeups"); window.location.assign(location + "/manage_makeups");
} else if (this.id == 'manage_attached_button') { } else if (this.id == 'manage_attached_button') {
console.log('coming soon...'); console.log('coming soon...');
} else if (this.id == 'manage_shifts_button') { } else if (this.id == 'manage_shift_registrations_button') {
console.log('coming soon...'); window.location.assign(location + "/manage_shift_registrations");
} else if (this.id == 'manage_leaves_button') { } else if (this.id == 'manage_leaves_button') {
console.log('coming soon...'); console.log('coming soon...');
} }
......
...@@ -255,6 +255,7 @@ function update_members_makeups(member_ids, action) { ...@@ -255,6 +255,7 @@ function update_members_makeups(member_ids, action) {
function display_possible_members() { function display_possible_members() {
$('.search_member_results_area').show(); $('.search_member_results_area').show();
$('.search_member_results').empty(); $('.search_member_results').empty();
$('.btn_possible_member').off();
let no_result = true; let no_result = true;
...@@ -276,39 +277,40 @@ function display_possible_members() { ...@@ -276,39 +277,40 @@ function display_possible_members() {
$('.search_member_results').append(member_button); $('.search_member_results').append(member_button);
// Set action on member button click }
$('.btn_possible_member').on('click', function() {
for (member of members_search_results) { // Set action on member button click
if (member.id == $(this).attr('member_id')) { $('.btn_possible_member').on('click', function() {
if (makeups_members === null) { for (member of members_search_results) {
makeups_members = []; if (member.id == $(this).attr('member_id')) {
} if (makeups_members === null) {
makeups_members = [];
makeups_members.unshift({
id: member.id,
name: member.name,
makeups_to_do: 0,
shift_type: member.shift_type
});
openModal(
`Ajouter un rattrapage à ${member.name} ?`,
() => {
update_members_makeups([member.id], "increment");
members_search_results = [];
$('#search_member_input').val('');
$('.search_member_results_area').hide();
$('.search_member_results').empty();
},
"Confirmer",
false
);
break;
} }
makeups_members.unshift({
id: member.id,
name: member.name,
makeups_to_do: 0,
shift_type: member.shift_type
});
openModal(
`Ajouter un rattrapage à ${member.name} ?`,
() => {
update_members_makeups([member.id], "increment");
members_search_results = [];
$('#search_member_input').val('');
$('.search_member_results_area').hide();
$('.search_member_results').empty();
},
"Confirmer",
false
);
break;
} }
}); }
} });
} }
if (no_result === true) { if (no_result === true) {
......
var member_shifts_table = null,
members_search_results = [],
selected_member = null,
incoming_shifts = null;
/**
* Load partners who have makeups to do
*/
function load_member_future_shifts() {
$.ajax({
type: 'GET',
url: "/shifts/get_list_shift_partner/" + selected_member.id,
dataType:"json",
traditional: true,
contentType: "application/json; charset=utf-8",
success: function(data) {
incoming_shifts = data;
display_member_shifts();
},
error: function(data) {
err = {msg: "erreur serveur lors de la récupération des services du membre", ctx: 'load_member_future_shifts'};
if (typeof data.responseJSON != 'undefined' && typeof data.responseJSON.error != 'undefined') {
err.msg += ' : ' + data.responseJSON.error;
}
report_JS_error(err, 'members.admin');
closeModal();
alert('Erreur lors de la récupération des services du membre.');
}
});
}
/**
* Display table of member future shifts
*/
function display_member_shifts() {
if (member_shifts_table) {
$('#member_shifts_table').off();
member_shifts_table.clear().destroy();
$('#member_shifts_table').empty();
}
$('#table_top_area #member_name').text(selected_member.name);
$('#table_top_area').show();
member_shifts_table = $('#member_shifts_table').DataTable({
data: incoming_shifts,
columns: [
{
data: "date_begin",
title: "",
visible: false
},
{
data: "shift_id",
title: "Service",
orderable: false,
render: function (data) {
return data[1];
}
},
{
data: null,
title: "",
className: "dt-body-center",
orderable: false,
width: "5%",
render: function () {
return `<i class="fa fa-lg fa-times delete_shift_registration"></i>`;
}
}
],
order: [
[
0,
"asc"
]
],
paging: false,
dom: 'tif',
oLanguage: {
"sProcessing": "Traitement en cours...",
"sSearch": "Rechercher dans le tableau",
"sInfo": "Total de _TOTAL_ &eacute;l&eacute;ments",
"sInfoEmpty": "",
"sInfoFiltered": "(filtr&eacute; de _MAX_ &eacute;l&eacute;ments au total)",
"sInfoPostFix": "",
"sLoadingRecords": "Chargement en cours...",
"sZeroRecords": "Aucun &eacute;l&eacute;ment &agrave; afficher",
"sEmptyTable": "Aucun futur service pour ce.tte membre"
}
});
$('#member_shifts_table').on('click', 'tbody td .delete_shift_registration', function () {
const row_data = member_shifts_table.row($(this).parents('tr')).data();
const shift_reg_id = row_data.id;
openModal(
`Enlever la présence de ${member.name} au service du ${row_data.shift_id[1]} ?`,
() => {
delete_shift_registration(shift_reg_id);
},
"Confirmer",
false
);
});
}
/**
* Send request to delete shift registration
* @param {Int} shift_reg_id Id of the shift_registration to delete
*/
function delete_shift_registration(shift_reg_id) {
openModal();
data = {
member_id: selected_member.id,
shift_registration_id: shift_reg_id
};
$.ajax({
type: 'POST',
url: "/members/delete_shift_registration",
data: JSON.stringify(data),
dataType:"json",
traditional: true,
contentType: "application/json; charset=utf-8",
success: function() {
closeModal();
alert("La présence a bien été annulée.");
const i = incoming_shifts.findIndex(is => is.id === shift_reg_id);
incoming_shifts.splice(i, 1);
display_member_shifts();
},
error: function(data) {
err = {msg: "erreur serveur pour supprimer la présence au service", ctx: 'delete_shift_registration'};
if (typeof data.responseJSON != 'undefined' && typeof data.responseJSON.error != 'undefined') {
err.msg += ' : ' + data.responseJSON.error;
}
report_JS_error(err, 'members.admin');
closeModal();
alert('Erreur serveur pour supprimer la présence au service. Ré-essayez plus tard.');
}
});
}
/**
* Display the members from the search result
*/
function display_possible_members() {
$('.search_member_results_area').show();
$('.search_member_results').empty();
$('.btn_possible_member').off();
let no_result = true;
if (members_search_results.length > 0) {
for (member of members_search_results) {
$(".search_results_text").show();
no_result = false;
// 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() {
for (member of members_search_results) {
if (member.id == $(this).attr('member_id')) {
selected_member = member;
load_member_future_shifts();
$('.search_member_results').empty();
$('.search_member_results_area').hide();
$('#search_member_input').val('');
break;
}
}
});
}
if (no_result === true) {
$(".search_results_text").hide();
$('.search_member_results').html(`<p>
<i>Aucun résultat ! Vérifiez votre recherche, ou si le.la membre n'est pas déjà dans le tableau...</i>
</p>`);
}
}
$(document).ready(function() {
if (coop_is_connected()) {
$.ajaxSetup({ headers: { "X-CSRFToken": getCookie('csrftoken') } });
$(".page_content").show();
} else {
$(".page_content").hide();
}
$('#back_to_admin_index').on('click', function() {
let base_location = window.location.href.split("manage_shift_registrations")[0].slice(0, -1);
window.location.assign(base_location);
});
// Set action to search for the member
$('#search_member_form').submit(function() {
let search_str = $('#search_member_input').val();
$.ajax({
url: '/members/search/' + search_str,
dataType : 'json',
success: function(data) {
members_search_results = [];
for (member of data.res) {
if (member.is_member || member.is_associated_people) {
members_search_results.push(member);
}
}
display_possible_members();
},
error: function() {
err = {
msg: "erreur serveur lors de la recherche de membres",
ctx: 'search_member_form.search_members'
};
report_JS_error(err, 'members.admin');
$.notify("Erreur lors de la recherche de membre, il faut ré-essayer plus tard...", {
globalPosition:"top right",
className: "error"
});
}
});
});
});
...@@ -56,6 +56,8 @@ urlpatterns = [ ...@@ -56,6 +56,8 @@ urlpatterns = [
# BDM - members admin # BDM - members admin
url(r'^admin$', admin.admin), url(r'^admin$', admin.admin),
url(r'^admin/manage_makeups$', admin.manage_makeups), url(r'^admin/manage_makeups$', admin.manage_makeups),
url(r'^admin/manage_shift_registrations$', admin.manage_shift_registrations),
url(r'^get_makeups_members$', admin.get_makeups_members), url(r'^get_makeups_members$', admin.get_makeups_members),
url(r'^update_members_makeups$', admin.update_members_makeups), url(r'^update_members_makeups$', admin.update_members_makeups),
url(r'^delete_shift_registration$', admin.delete_shift_registration),
] ]
...@@ -237,7 +237,7 @@ def update_couchdb_barcodes(request): ...@@ -237,7 +237,7 @@ def update_couchdb_barcodes(request):
def search(request, needle, shift_id): def search(request, needle, shift_id):
"""Search member has been requested.""" """Search member has been requested."""
search_type = request.GET.get('search_type', '') search_type = request.GET.get('search_type', "full")
try: try:
key = int(needle) key = int(needle)
......
...@@ -25,17 +25,16 @@ ...@@ -25,17 +25,16 @@
Gestion des rattragapes Gestion des rattragapes
<span class="management_type_button_icons"><i class="fas fa-arrow-right"></i></span> <span class="management_type_button_icons"><i class="fas fa-arrow-right"></i></span>
</button><br> </button><br>
<button type="button" class="btn--primary management_type_button" id="manage_attached_button"> <button type="button" class="btn--primary management_type_button" id="manage_shift_registrations_button">
Gestion des binômes Gestion des présences
<span class="management_type_button_icons"><i class="fas fa-wrench"></i></span> <span class="management_type_button_icons"><i class="fas fa-arrow-right"></i></span>
{# <span class="management_type_button_icons"><i class="fas fa-arrow-right"></i></span> #}
</button><br> </button><br>
<button type="button" class="btn--primary management_type_button" id="manage_shifts_button"> <button type="button" class="btn--primary management_type_button" id="manage_attached_button" disabled>
Gestion des créneaux Gestion des binômes
<span class="management_type_button_icons"><i class="fas fa-wrench"></i></span> <span class="management_type_button_icons"><i class="fas fa-wrench"></i></span>
{# <span class="management_type_button_icons"><i class="fas fa-arrow-right"></i></span> #} {# <span class="management_type_button_icons"><i class="fas fa-arrow-right"></i></span> #}
</button><br> </button><br>
<button type="button" class="btn--primary management_type_button" id="manage_leaves_button"> <button type="button" class="btn--primary management_type_button" id="manage_leaves_button" disabled>
Gestion des congés Gestion des congés
<span class="management_type_button_icons"><i class="fas fa-wrench"></i></span> <span class="management_type_button_icons"><i class="fas fa-wrench"></i></span>
{# <span class="management_type_button_icons"><i class="fas fa-arrow-right"></i></span> #} {# <span class="management_type_button_icons"><i class="fas fa-arrow-right"></i></span> #}
......
{% extends "base.html" %}
{% load static %}
{% block additionnal_css %}
<link rel="stylesheet" href="{% static 'css/datatables/datatables.min.css' %}">
<link rel="stylesheet" href="{% static 'css/admin/manage_shift_registrations.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 id="back_to_admin_index">
<button type="button" class="btn--danger"><i class="fas fa-arrow-left"></i>&nbsp; Retour</button>
</div>
<div class="login_area">
{% include "common/conn_admin.html" %}
</div>
<div class="header txtcenter">
<h1>Gestion des Présences</h1>
</div>
<div class="page_content">
<div id="search_member_area">
<div id="search_member_form_area">
<h4>Rechercher un.e membre</h4>
<form id="search_member_form" action="javascript:;" method="post">
<input type="text" id="search_member_input" value="" placeholder="Nom ou numéro du coop..." required>
<button type="submit" class="btn--primary" id="search_member_button">Recherche</button>
</form>
</div>
<div class="search_member_results_area" style="display:none;">
<div class="search_results_text">
<p><i>Choisissez parmi les membres trouvés :</i></p>
</div>
<div class="search_member_results"></div>
</div>
</div>
<div id="table_top_area">
<h3>Liste des futurs services de <span id="member_name"></span></h3>
</div>
<div class="table_area">
<table id="member_shifts_table" class="display" cellspacing="0" width="100%"></table>
</div>
</div>
<div id="templates" style="display:none;"></div>
</div>
<script src='{% static "js/all_common.js" %}?v='></script>
<script src='{% static "js/admin/manage_shift_registrations.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