Commit afe5a5e8 by Etienne Freiss

Merge branch '2425-delete-future-registration' into 'dev_cooperatic'

2425 delete future registration

See merge request !133
parents 3f8e967a ba8cceb1
Pipeline #1886 passed with stage
in 1 minute 30 seconds
...@@ -905,6 +905,19 @@ class CagetteMember(models.Model): ...@@ -905,6 +905,19 @@ class CagetteMember(models.Model):
return res return res
def update_extra_shift_done(self, value):
api = OdooAPI()
res = {}
f = { 'extra_shift_done': value }
res_item = api.update('res.partner', [self.id], f)
res = {
'mid': self.id,
'update': res_item
}
return res
class CagetteMembers(models.Model): class CagetteMembers(models.Model):
"""Class to manage operations on all members or part of them.""" """Class to manage operations on all members or part of them."""
......
...@@ -54,6 +54,13 @@ ...@@ -54,6 +54,13 @@
margin: 3rem 0; margin: 3rem 0;
} }
#my_info .choose_makeups,
#my_info .unsuscribed_form_link,
#my_info .remove_future_registration {
font-size: 1.8rem;
word-break: normal;
}
#my_info #member_status_action, #my_info #member_status_action,
#my_info .member_shift_name_area, #my_info .member_shift_name_area,
#my_info .member_coop_number_area { #my_info .member_coop_number_area {
......
...@@ -90,6 +90,14 @@ ...@@ -90,6 +90,14 @@
border-radius: 5px; border-radius: 5px;
} }
.delete_registration_button {
justify-content: center;
align-items: center;
margin: 0.75rem 15px;
color: #d9534f;
cursor: pointer;
display: none;
}
/* -- Calendar screen, makeups message */ /* -- Calendar screen, makeups message */
...@@ -113,6 +121,21 @@ ...@@ -113,6 +121,21 @@
} }
} }
/* -- Calendar screen, can delete registrations message */
#can_delete_future_registrations_area {
display: none;
align-self: center;
margin: 0 1rem 1rem 1rem;
padding: 1rem 1.25rem;
}
#can_delete_future_registrations_area button {
white-space: normal;
word-break: normal;
margin: 1rem;
}
/* -- Calendar screen, calendar */ /* -- Calendar screen, calendar */
#calendar { #calendar {
......
...@@ -166,6 +166,11 @@ body { ...@@ -166,6 +166,11 @@ body {
font-size: 1.5rem; font-size: 1.5rem;
} }
.remove_future_registration {
display: none;
white-space: normal;
}
.unsuscribed_form_link { .unsuscribed_form_link {
display: none; display: none;
text-decoration: none; text-decoration: none;
......
...@@ -20,7 +20,7 @@ function init_faq() { ...@@ -20,7 +20,7 @@ function init_faq() {
} }
$(document).on('click', "#shift_exchange_btn", () => { $(document).on('click', "#shift_exchange_btn", () => {
goto('echange-de-services'); goto('echange-de-services');
}); });
$(document).on('click', '.accordion', function() { $(document).on('click', '.accordion', function() {
......
...@@ -68,8 +68,7 @@ function prepare_server_data(data) { ...@@ -68,8 +68,7 @@ function prepare_server_data(data) {
if (history_item.associate_registered == false || history_item.associate_registered == undefined) { if (history_item.associate_registered == false || history_item.associate_registered == undefined) {
history_item.associate_registered = ""; history_item.associate_registered = "";
} } else {
else {
if (partner_data.associated_partner_id != "False") { if (partner_data.associated_partner_id != "False") {
if (history_item.associate_registered==="partner") { if (history_item.associate_registered==="partner") {
history_item.associate_registered = partner_data.name; history_item.associate_registered = partner_data.name;
......
...@@ -147,7 +147,7 @@ function prepare_shift_line_template(date_begin) { ...@@ -147,7 +147,7 @@ function prepare_shift_line_template(date_begin) {
shift_line_template.find(".shift_line_date").text(f_date_shift_start); shift_line_template.find(".shift_line_date").text(f_date_shift_start);
shift_line_template.find(".shift_line_time").text(datetime_shift_start.toLocaleTimeString("fr-fr", time_options)); shift_line_template.find(".shift_line_time").text(datetime_shift_start.toLocaleTimeString("fr-fr", time_options));
return shift_line_template; return shift_line_template;
} }
...@@ -158,6 +158,7 @@ function prepare_shift_line_template(date_begin) { ...@@ -158,6 +158,7 @@ function prepare_shift_line_template(date_begin) {
*/ */
function init_my_info_data() { function init_my_info_data() {
$(".choose_makeups").off(); $(".choose_makeups").off();
$(".remove_future_registration").off();
$(".unsuscribed_form_link").off(); $(".unsuscribed_form_link").off();
$(".member_shift_name").text(partner_data.regular_shift_name); $(".member_shift_name").text(partner_data.regular_shift_name);
...@@ -223,6 +224,13 @@ function init_my_info_data() { ...@@ -223,6 +224,13 @@ function init_my_info_data() {
} }
} }
if (partner_data.extra_shift_done > 0) {
$(".remove_future_registration").show();
$(".remove_future_registration").on('click', () => {
goto('echange-de-services');
});
}
$(".member_coop_number").text(partner_data.barcode_base); $(".member_coop_number").text(partner_data.barcode_base);
} }
...@@ -257,7 +265,7 @@ $(document).ready(function() { ...@@ -257,7 +265,7 @@ $(document).ready(function() {
// debouncing function from John Hann // debouncing function from John Hann
// http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/ // http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
var debounce = function (func, threshold, execAsap) { var debounce = function (func, threshold, execAsap) {
var timeout; var timeout = null;
return function debounced () { return function debounced () {
var obj = this, args = arguments; var obj = this, args = arguments;
......
...@@ -12,5 +12,6 @@ urlpatterns = [ ...@@ -12,5 +12,6 @@ urlpatterns = [
url(r'^faqBDM$', views.faqBDM), url(r'^faqBDM$', views.faqBDM),
url(r'^no_content$', views.no_content), url(r'^no_content$', views.no_content),
url(r'^get_shifts_history$', views.get_shifts_history), url(r'^get_shifts_history$', views.get_shifts_history),
url(r'^offer_extra_shift$', views.offer_extra_shift),
url(r'^.*', views.index) # Urls unknown from the server will redirect to index url(r'^.*', views.index) # Urls unknown from the server will redirect to index
] ]
...@@ -99,6 +99,7 @@ def index(request, exception=None): ...@@ -99,6 +99,7 @@ def index(request, exception=None):
partnerData["parent_id"] = partnerData["parent_id"][0] partnerData["parent_id"] = partnerData["parent_id"][0]
md5_calc = hashlib.md5(partnerData['parent_create_date'].encode('utf-8')).hexdigest() md5_calc = hashlib.md5(partnerData['parent_create_date'].encode('utf-8')).hexdigest()
partnerData['parent_verif_token'] = md5_calc partnerData['parent_verif_token'] = md5_calc
partnerData['extra_shift_done'] = partnerData["parent_extra_shift_done"]
else: else:
partnerData["parent_name"] = False partnerData["parent_name"] = False
...@@ -234,4 +235,13 @@ def get_shifts_history(request): ...@@ -234,4 +235,13 @@ def get_shifts_history(request):
date_from = getattr(settings, 'START_DATE_FOR_SHIFTS_HISTORY', '2018-01-01') date_from = getattr(settings, 'START_DATE_FOR_SHIFTS_HISTORY', '2018-01-01')
res["data"] = m.get_shifts_history(partner_id, limit, offset, date_from) res["data"] = m.get_shifts_history(partner_id, limit, offset, date_from)
return JsonResponse(res) return JsonResponse(res)
\ No newline at end of file
def offer_extra_shift(request):
res = {}
partner_id = int(request.POST['partner_id'])
m = CagetteMember(partner_id)
res = m.update_extra_shift_done(0)
return JsonResponse(res)
...@@ -38,17 +38,18 @@ class CagetteShift(models.Model): ...@@ -38,17 +38,18 @@ class CagetteShift(models.Model):
'cooperative_state', 'final_standard_point', 'create_date', 'cooperative_state', 'final_standard_point', 'create_date',
'final_ftop_point', 'shift_type', 'leave_ids', 'makeups_to_do', 'barcode_base', 'final_ftop_point', 'shift_type', 'leave_ids', 'makeups_to_do', 'barcode_base',
'street', 'street2', 'zip', 'city', 'mobile', 'phone', 'email', 'street', 'street2', 'zip', 'city', 'mobile', 'phone', 'email',
'is_associated_people', 'parent_id'] 'is_associated_people', 'parent_id', 'extra_shift_done']
partnerData = self.o_api.search_read('res.partner', cond, fields, 1) partnerData = self.o_api.search_read('res.partner', cond, fields, 1)
if partnerData: if partnerData:
partnerData = partnerData[0] partnerData = partnerData[0]
if partnerData['is_associated_people']: if partnerData['is_associated_people']:
cond = [['id', '=', partnerData['parent_id'][0]]] cond = [['id', '=', partnerData['parent_id'][0]]]
fields = ['create_date'] fields = ['create_date', 'extra_shift_done']
parentData = self.o_api.search_read('res.partner', cond, fields, 1) parentData = self.o_api.search_read('res.partner', cond, fields, 1)
if parentData: if parentData:
partnerData['parent_create_date'] = parentData[0]['create_date'] partnerData['parent_create_date'] = parentData[0]['create_date']
partnerData['parent_extra_shift_done'] = parentData[0]['extra_shift_done']
if partnerData['shift_type'] == 'standard': if partnerData['shift_type'] == 'standard':
partnerData['in_ftop_team'] = False partnerData['in_ftop_team'] = False
...@@ -91,7 +92,7 @@ class CagetteShift(models.Model): ...@@ -91,7 +92,7 @@ class CagetteShift(models.Model):
def get_shift_partner(self, id): def get_shift_partner(self, id):
"""Récupère les shift du membre""" """Récupère les shift du membre"""
fields = ['date_begin', 'date_end','final_standard_point', fields = ['date_begin', 'date_end','final_standard_point',
'shift_id', 'shift_type','partner_id', "id", "associate_registered"] # res.partner 'shift_id', 'shift_type','partner_id', "id", "associate_registered", "is_makeup"] # res.partner
cond = [['partner_id.id', '=', id],['state', '=', 'open'], cond = [['partner_id.id', '=', id],['state', '=', 'open'],
['date_begin', '>', datetime.datetime.now().isoformat()]] ['date_begin', '>', datetime.datetime.now().isoformat()]]
shiftData = self.o_api.search_read('shift.registration', cond, fields, order ="date_begin ASC") shiftData = self.o_api.search_read('shift.registration', cond, fields, order ="date_begin ASC")
......
...@@ -15,6 +15,7 @@ urlpatterns = [ ...@@ -15,6 +15,7 @@ urlpatterns = [
url(r'^change_shift', views.change_shift), url(r'^change_shift', views.change_shift),
url(r'^affect_shift', views.affect_shift), url(r'^affect_shift', views.affect_shift),
url(r'^add_shift', views.add_shift), url(r'^add_shift', views.add_shift),
url(r'^cancel_shift', views.cancel_shift),
url(r'^request_delay', views.request_delay), url(r'^request_delay', views.request_delay),
url(r'^reset_members_positive_points', views.reset_members_positive_points) url(r'^reset_members_positive_points', views.reset_members_positive_points)
] ]
...@@ -310,6 +310,37 @@ def add_shift(request): ...@@ -310,6 +310,37 @@ def add_shift(request):
else: else:
return HttpResponseForbidden() return HttpResponseForbidden()
def cancel_shift(request):
""" Annule une présence à un shift """
if 'verif_token' in request.POST:
partner_id = int(request.POST.get('idPartner'))
if Verification.verif_token(request.POST.get('verif_token'), partner_id) is True:
cs = CagetteShift()
listRegister = [int(request.POST['idRegister'])]
try:
response = cs.cancel_shift(listRegister)
# decrement extra_shift_done if param exists
if 'extra_shift_done' in request.POST:
target = int(request.POST["extra_shift_done"]) - 1
# extra security
if target < 0:
target = 0
cm = CagetteMember(partner_id)
cm.update_extra_shift_done(target)
return JsonResponse({"res" : 'response'})
except Exception as e:
return JsonResponse({"error" : str(e)}, status=500)
else:
return HttpResponseForbidden()
else:
return HttpResponseForbidden()
def request_delay(request): def request_delay(request):
if 'verif_token' in request.POST: if 'verif_token' in request.POST:
if Verification.verif_token(request.POST.get('verif_token'), int(request.POST.get('idPartner'))) is True: if Verification.verif_token(request.POST.get('verif_token'), int(request.POST.get('idPartner'))) is True:
......
...@@ -21,6 +21,9 @@ ...@@ -21,6 +21,9 @@
<button type="button" class="btn--danger choose_makeups"> <button type="button" class="btn--danger choose_makeups">
Je sélectionne mes rattrapages Je sélectionne mes rattrapages
</button> </button>
<button type="button" class="btn--success remove_future_registration">
J'ai validé un service à deux, je peux supprimer une présence
</button>
</div> </div>
<div class="member_shift_name_area"> <div class="member_shift_name_area">
<span>Mon créneau : </span> <span>Mon créneau : </span>
......
...@@ -36,18 +36,20 @@ ...@@ -36,18 +36,20 @@
</div> </div>
<div id="selectable_shift_line_template"> <div id="selectable_shift_line_template">
<div class="d-flex"> <div class="d-flex shift_line_container">
<div class="selectable_shift_line btn--primary"> <div class="selectable_shift_line btn--primary">
<input type="checkbox" class="checkbox"> <input type="checkbox" class="checkbox">
<div class="selectable_shift_line_text"> <div class="selectable_shift_line_text">
<span class="shift_line_date"></span> - <span class="shift_line_time"></span> <span class="shift_line_date"></span> - <span class="shift_line_time"></span>
</div> </div>
</div> </div>
<div class="affect_associate_registered button--warning"> <div class="affect_associate_registered button--warning"></div>
</div>
</div> </div>
</div> </div>
<div id="delete_registration_button_template">
<div class="delete_registration_button"><i class="fas fa-lg fa-trash"></i></div>
</div>
<div id="modal_affect_shift"> <div id="modal_affect_shift">
<div>Qui sera présent.e ?</div> <div>Qui sera présent.e ?</div>
...@@ -58,7 +60,6 @@ ...@@ -58,7 +60,6 @@
<div id="shift_both" class=" btn--primary"> <div id="shift_both" class=" btn--primary">
Les deux Les deux
</div> </div>
</div> </div>
<div id="modal_shift_exchange_template"> <div id="modal_shift_exchange_template">
...@@ -140,7 +141,8 @@ ...@@ -140,7 +141,8 @@
"associated_partner_name" : "{{partnerData.associated_partner_name}}", "associated_partner_name" : "{{partnerData.associated_partner_name}}",
"verif_token" : "{{partnerData.verif_token}}", "verif_token" : "{{partnerData.verif_token}}",
"leave_stop_date": "{{partnerData.leave_stop_date}}", "leave_stop_date": "{{partnerData.leave_stop_date}}",
"comite": "{{partnerData.comite}}" "comite": "{{partnerData.comite}}",
"extra_shift_done": parseInt("{{partnerData.extra_shift_done}}", 10)
}; };
var block_actions_for_attached_people = '{{block_actions_for_attached_people}}'; var block_actions_for_attached_people = '{{block_actions_for_attached_people}}';
</script> </script>
......
...@@ -25,6 +25,9 @@ ...@@ -25,6 +25,9 @@
<button type="button" class="btn--danger choose_makeups"> <button type="button" class="btn--danger choose_makeups">
Je sélectionne mes rattrapages Je sélectionne mes rattrapages
</button> </button>
<button type="button" class="btn--success remove_future_registration">
J'ai validé un service à deux, je peux supprimer une présence
</button>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -35,6 +35,14 @@ ...@@ -35,6 +35,14 @@
<span class="select_makeups_message_block">Je dois les sélectionner dans le calendrier. </span> <span class="select_makeups_message_block">Je dois les sélectionner dans le calendrier. </span>
<span class="select_makeups_message_block">Je ne peux pas échanger de service tant que je n'ai pas choisi mes rattrapages. </span> <span class="select_makeups_message_block">Je ne peux pas échanger de service tant que je n'ai pas choisi mes rattrapages. </span>
</div> </div>
<div id="can_delete_future_registrations_area">
<button class="btn--success can_delete_future_registrations_button" id="delete_future_registration">
J'ai validé <span class="extra_shift_done"></span> service(s) à deux, je supprime un service futur
</button>
<button class="btn--success can_delete_future_registrations_button" id="offer_extra_shift">
Je souhaite donner <span class="extra_shift_done"></span> service(s) d'avance à la communauté
</button>
</div>
<div id="calendar_top_info"> <div id="calendar_top_info">
<div id="partner_shifts_list"> <div id="partner_shifts_list">
<h4>Liste de mes services :</h4> <h4>Liste de mes services :</h4>
......
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