Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
T
third-party
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
2
Merge Requests
2
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cooperatic-foodcoops
third-party
Commits
52f4db76
Commit
52f4db76
authored
Feb 22, 2022
by
Damien Moulard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
interface to remove members shift registrations
parent
e6577d4f
Pipeline
#1837
passed with stage
in 1 minute 28 seconds
Changes
9
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
453 additions
and
41 deletions
+453
-41
admin.py
members/admin.py
+30
-0
manage_shift_registrations.css
members/static/css/admin/manage_shift_registrations.css
+76
-0
bdm_index.js
members/static/js/admin/bdm_index.js
+2
-2
manage_makeups.js
members/static/js/admin/manage_makeups.js
+33
-31
manage_shift_registrations.js
members/static/js/admin/manage_shift_registrations.js
+245
-0
urls.py
members/urls.py
+2
-0
views.py
members/views.py
+1
-1
index.html
templates/members/admin/index.html
+6
-7
manage_shift_registrations.html
templates/members/admin/manage_shift_registrations.html
+58
-0
No files found.
members/admin.py
View file @
52f4db76
...
...
@@ -4,6 +4,7 @@ from outils.for_view_imports import *
from
members.models
import
CagetteUser
from
members.models
import
CagetteMembers
from
members.models
import
CagetteMember
from
shifts.models
import
CagetteShift
from
outils.common
import
MConfig
...
...
@@ -318,6 +319,13 @@ def manage_makeups(request):
'module'
:
'Membres'
}
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
):
""" Récupération des membres qui doivent faire des rattrapages """
res
=
CagetteMembers
.
get_makeups_members
()
...
...
@@ -370,3 +378,24 @@ def update_members_makeups(request):
res
[
"message"
]
=
"Unauthorized"
response
=
JsonResponse
(
res
,
status
=
403
)
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
members/static/css/admin/manage_shift_registrations.css
0 → 100644
View file @
52f4db76
.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
members/static/js/admin/bdm_index.js
View file @
52f4db76
...
...
@@ -11,8 +11,8 @@ $(document).ready(function() {
window
.
location
.
assign
(
location
+
"/manage_makeups"
);
}
else
if
(
this
.
id
==
'manage_attached_button'
)
{
console
.
log
(
'coming soon...'
);
}
else
if
(
this
.
id
==
'manage_shifts_button'
)
{
console
.
log
(
'coming soon...'
);
}
else
if
(
this
.
id
==
'manage_shift
_registration
s_button'
)
{
window
.
location
.
assign
(
location
+
"/manage_shift_registrations"
);
}
else
if
(
this
.
id
==
'manage_leaves_button'
)
{
console
.
log
(
'coming soon...'
);
}
...
...
members/static/js/admin/manage_makeups.js
View file @
52f4db76
...
...
@@ -255,6 +255,7 @@ function update_members_makeups(member_ids, action) {
function
display_possible_members
()
{
$
(
'.search_member_results_area'
).
show
();
$
(
'.search_member_results'
).
empty
();
$
(
'.btn_possible_member'
).
off
();
let
no_result
=
true
;
...
...
@@ -276,39 +277,40 @@ function display_possible_members() {
$
(
'.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'
))
{
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
;
}
// 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'
))
{
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
;
}
}
);
}
}
}
);
}
if
(
no_result
===
true
)
{
...
...
members/static/js/admin/manage_shift_registrations.js
0 → 100644
View file @
52f4db76
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_ éléments"
,
"sInfoEmpty"
:
""
,
"sInfoFiltered"
:
"(filtré de _MAX_ éléments au total)"
,
"sInfoPostFix"
:
""
,
"sLoadingRecords"
:
"Chargement en cours..."
,
"sZeroRecords"
:
"Aucun élément à 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"
});
}
});
});
});
members/urls.py
View file @
52f4db76
...
...
@@ -56,6 +56,8 @@ urlpatterns = [
# BDM - members admin
url
(
r'^admin$'
,
admin
.
admin
),
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'^update_members_makeups$'
,
admin
.
update_members_makeups
),
url
(
r'^delete_shift_registration$'
,
admin
.
delete_shift_registration
),
]
members/views.py
View file @
52f4db76
...
...
@@ -237,7 +237,7 @@ def update_couchdb_barcodes(request):
def
search
(
request
,
needle
,
shift_id
):
"""Search member has been requested."""
search_type
=
request
.
GET
.
get
(
'search_type'
,
''
)
search_type
=
request
.
GET
.
get
(
'search_type'
,
"full"
)
try
:
key
=
int
(
needle
)
...
...
templates/members/admin/index.html
View file @
52f4db76
...
...
@@ -25,17 +25,16 @@
Gestion des rattragapes
<span
class=
"management_type_button_icons"
><i
class=
"fas fa-arrow-right"
></i></span>
</button><br>
<button
type=
"button"
class=
"btn--primary management_type_button"
id=
"manage_attached_button"
>
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-arrow-right"
></i></span>
#}
<button
type=
"button"
class=
"btn--primary management_type_button"
id=
"manage_shift_registrations_button"
>
Gestion des présences
<span
class=
"management_type_button_icons"
><i
class=
"fas fa-arrow-right"
></i></span>
</button><br>
<button
type=
"button"
class=
"btn--primary management_type_button"
id=
"manage_
shifts_button"
>
Gestion des
créneaux
<button
type=
"button"
class=
"btn--primary management_type_button"
id=
"manage_
attached_button"
disabled
>
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-arrow-right"
></i></span>
#}
</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
<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>
#}
...
...
templates/members/admin/manage_shift_registrations.html
0 → 100644
View file @
52f4db76
{% 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>
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 %}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment