Commit b5ae60ba by Etienne Freiss

Merge branch 'dev_cooperatic' into 2251-shift-screen-associate

parents 7efbf85d afe5a5e8
Pipeline #1899 passed with stage
in 1 minute 30 seconds
...@@ -13,6 +13,7 @@ import pytz ...@@ -13,6 +13,7 @@ import pytz
import locale import locale
import re import re
import dateutil.parser import dateutil.parser
from datetime import date
...@@ -350,6 +351,23 @@ class CagetteMember(models.Model): ...@@ -350,6 +351,23 @@ class CagetteMember(models.Model):
return answer return answer
@staticmethod @staticmethod
def is_associated(id_parent):
api = OdooAPI()
cond = [['parent_id', '=', int(id_parent)]]
fields = ['id','name','parent_id','birthdate']
res = api.search_read('res.partner', cond, fields, 10, 0, 'id DESC')
already_have_adult_associated = False
for partner in res:
birthdate = partner['birthdate']
if(birthdate):
today = date.today()
date1 = datetime.datetime.strptime(birthdate, "%Y-%m-%d")
age = today.year - date1.year - ((today.month, today.day) < (date1.month, date1.day))
if age > 17 :
already_have_adult_associated = True
return already_have_adult_associated
@staticmethod
def finalize_coop_creation(post_data): def finalize_coop_creation(post_data):
""" Update coop data. """ """ Update coop data. """
res = {} res = {}
...@@ -505,7 +523,30 @@ class CagetteMember(models.Model): ...@@ -505,7 +523,30 @@ class CagetteMember(models.Model):
m.create_capital_subscription_invoice(post_data['shares_euros'], today) m.create_capital_subscription_invoice(post_data['shares_euros'], today)
res['bc'] = m.generate_base_and_barcode(post_data) res['bc'] = m.generate_base_and_barcode(post_data)
# Create shift suscription # if the new member is associated with an already existing member
# then we put the state in "associated" and we create the "associated" member
if 'is_associated_people' in post_data and 'parent_id' in post_data :
fields = {}
fields['cooperative_state'] = 'associated'
api.update('res.partner', [partner_id], fields)
associated_member = {
'email': post_data['_id'],
'name': name,
'birthdate': birthdate,
'sex': sex,
'street': post_data['address'],
'zip': post_data['zip'],
'city': post_data['city'],
'phone': format_phone_number(post_data['mobile']), # Because list view default show Phone and people mainly gives mobile
'barcode_rule_id': settings.COOP_BARCODE_RULE_ID,
'parent_id' : post_data['parent_id'],
'is_associated_people': True
}
associated_member_id = api.create('res.partner', associated_member)
# If it's an new associated member with a new partner. Link will be made by the user in BDM/admin
# We add the associated member to the "associate" shift template so we can find them in Odoo
elif 'is_associated_people' not in post_data or 'is_associated_people' in post_data and 'parent_id' not in post_data:
# Create shift suscription if is not associated
shift_template = json.loads(post_data['shift_template']) shift_template = json.loads(post_data['shift_template'])
shift_t_id = shift_template['data']['id'] shift_t_id = shift_template['data']['id']
stype = shift_template['data']['type'] stype = shift_template['data']['type']
...@@ -864,6 +905,19 @@ class CagetteMember(models.Model): ...@@ -864,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."""
......
...@@ -26,3 +26,51 @@ ...@@ -26,3 +26,51 @@
#mail_generation {position:absolute; bottom:30px;} #mail_generation {position:absolute; bottom:30px;}
#sex {padding: 0;} #sex {padding: 0;}
#existing_partner{
padding-right: 15px;
width: 45%;
}
#new_partner{
padding-left: 15px;
width: 45%;
}
#add_binome{
cursor: pointer;
text-decoration: underline;
font-weight: bold;
}
#existing_member_choice, #new_member_choice{
border: 1px solid black;
width: 40%;
cursor: pointer;
text-align: center;
max-width: 400px;
background-color: #e7e9ed;
color: black;
padding: 1rem 1.5rem;
}
#existing_member_choice:hover, #new_member_choice:hover{
background-color: #ccc;
}
.choice_active{
background-color: #0275d8 !important;
color: white !important;
}
#existing_member_choice{
margin-right: 15px;
}
.choice_button_area{
margin-bottom: 10px;
}
#associate_area{
margin-bottom: 15px;
}
\ No newline at end of file
...@@ -17,8 +17,9 @@ var latest_odoo_coop_bb = null, ...@@ -17,8 +17,9 @@ var latest_odoo_coop_bb = null,
subs_cap = $('#subs_cap'), subs_cap = $('#subs_cap'),
m_barcode = $('#m_barcode'), m_barcode = $('#m_barcode'),
sex = $('#sex'), sex = $('#sex'),
self_records = [], self_records = [],
selected_associate=null,
associated_old_choice= null,
choose_shift_msg = "Il est nécessaire de choisir un créneau (ABCD ou Volant) avant de pouvoir faire quoique ce soit d'autre.\nUne personne qui souhaite être rattachée au compte d'un autre membre dans le cadre d'un binôme doit choisir le créneau volant."; choose_shift_msg = "Il est nécessaire de choisir un créneau (ABCD ou Volant) avant de pouvoir faire quoique ce soit d'autre.\nUne personne qui souhaite être rattachée au compte d'un autre membre dans le cadre d'un binôme doit choisir le créneau volant.";
...@@ -106,6 +107,11 @@ function reset_sex_radios() { ...@@ -106,6 +107,11 @@ function reset_sex_radios() {
} }
function create_new_coop() { function create_new_coop() {
selected_associate= null;
$('#associate_area').hide();
$('.chosen_associate').html("");
$('.chosen_associate_area').hide();
$('.member_choice').removeClass('choice_active');
local_in_process = getLocalInProcess(); local_in_process = getLocalInProcess();
if (getLocalInProcess().length > 0) { if (getLocalInProcess().length > 0) {
empty_waiting_local_processes(); empty_waiting_local_processes();
...@@ -129,7 +135,6 @@ function create_new_coop() { ...@@ -129,7 +135,6 @@ function create_new_coop() {
alert(choose_shift_msg); alert(choose_shift_msg);
} }
} }
} }
function swipe_to_shift_choice() { function swipe_to_shift_choice() {
ncoop_view.hide(); ncoop_view.hide();
...@@ -167,6 +172,30 @@ function _really_save_new_coop(email, fname, lname, cap, pm, cn, bc, msex) { ...@@ -167,6 +172,30 @@ function _really_save_new_coop(email, fname, lname, cap, pm, cn, bc, msex) {
coop.payment_meaning = pm; coop.payment_meaning = pm;
coop.checks_nb = cn; coop.checks_nb = cn;
coop.fingerprint = fingerprint; coop.fingerprint = fingerprint;
if (associated_old_choice == 'existing_member_choice') {
if (selected_associate!=null) {
coop.is_associated_people = true;
coop.parent_id=selected_associate.id;
coop.parent_name=selected_associate.barcode_base + ' - '+ selected_associate.name;
coop.shift_template = shift_templates[ASSOCIATE_MEMBER_SHIFT];
}
} else if (associated_old_choice == 'new_member_choice' && $('#new_member_input').val()!='') {
coop.is_associated_people = true;
coop.parent_name=$('#new_member_input').val();
delete coop.parent_id;
coop.shift_template = shift_templates[ASSOCIATE_MEMBER_SHIFT];
} else {
delete coop.is_associated_people;
delete coop.parent_id;
delete coop.parent_name;
}
selected_associate=null;
$('#new_member_input').val('');
$('#associate_area').hide();
$('.chosen_associate_area').hide();
$('.chosen_associate').html("");
associated_old_choice= null;
if (m_barcode.length > 0) coop.m_barcode = bc; if (m_barcode.length > 0) coop.m_barcode = bc;
if (sex.length > 0) coop.sex = msex; if (sex.length > 0) coop.sex = msex;
coop.validation_state = "to_fill"; coop.validation_state = "to_fill";
...@@ -174,11 +203,13 @@ function _really_save_new_coop(email, fname, lname, cap, pm, cn, bc, msex) { ...@@ -174,11 +203,13 @@ function _really_save_new_coop(email, fname, lname, cap, pm, cn, bc, msex) {
if (!err) { if (!err) {
coop._rev = result.rev; coop._rev = result.rev;
current_coop = coop; current_coop = coop;
if (typeof coop.shift_template != "undefined") { if (typeof coop.shift_template != "undefined" && coop.shift_template.data.id != ASSOCIATE_MEMBER_SHIFT) {
openModal( openModal(
'Voulez-vous modifier le créneau choisi ?', swipe_to_shift_choice, 'oui', 'Voulez-vous modifier le créneau choisi ?', swipe_to_shift_choice, 'oui',
false, true, show_coop_list false, true, show_coop_list
); );
} else if (coop.is_associated_people && typeof coop.shift_template != "undefined" && coop.shift_template.data.id == ASSOCIATE_MEMBER_SHIFT) {
ncoop_view.hide();
} else { } else {
swipe_to_shift_choice(); swipe_to_shift_choice();
} }
...@@ -226,8 +257,25 @@ function store_new_coop(event) { ...@@ -226,8 +257,25 @@ function store_new_coop(event) {
if (typeof(rData.answer) == 'boolean' && rData.answer == true) { if (typeof(rData.answer) == 'boolean' && rData.answer == true) {
errors.push("Il y a déjà un enregistrement Odoo avec cette adresse mail !"); errors.push("Il y a déjà un enregistrement Odoo avec cette adresse mail !");
} }
if (selected_associate!=null) {
$.ajax({url : '/members/is_associated/' + selected_associate.id,
dataType :'json'
}).done(function(rData) {
if (typeof(rData.answer) == 'boolean' && rData.answer == true) {
errors.push("Ce membre à déjà un Binôme majeur");
}
if (errors.length == 0) {
_really_save_new_coop(
email, fname, lname,
subs_cap.val(), payment_meaning.val(), ch_qty.val(), bc, msex
);
} else {
alert(errors.join("\n"));
}
}); });
} else {
if (errors.length == 0) { if (errors.length == 0) {
_really_save_new_coop( _really_save_new_coop(
email, fname, lname, email, fname, lname,
...@@ -237,6 +285,8 @@ function store_new_coop(event) { ...@@ -237,6 +285,8 @@ function store_new_coop(event) {
} else { } else {
alert(errors.join("\n")); alert(errors.join("\n"));
} }
}
});
} }
...@@ -273,6 +323,29 @@ function modify_current_coop() { ...@@ -273,6 +323,29 @@ function modify_current_coop() {
} else { } else {
ch_qty.hide(); ch_qty.hide();
} }
if (current_coop.is_associated_people) {
$('.member_choice').removeClass('choice_active');
$('#associate_area').show();
if (current_coop.parent_id) {
$('#existing_member_choice_action').show();
$('#new_member_choice_action').hide();
$('#existing_member_choice').addClass('choice_active');
var member_button = '<div>' + current_coop.parent_name + '</div>';
$('.chosen_associate').html(member_button);
$('.chosen_associate_area').show();
associated_old_choice = 'existing_member_choice';
} else {
$('#new_member_choice_action').show();
$('#existing_member_choice_action').hide();
$('#new_member_choice').addClass('choice_active');
$('#new_member_input').val(current_coop.parent_name);
$('.chosen_associate').html('');
$('.chosen_associate_area').hide();
associated_old_choice = 'new_member_choice';
}
}
subs_cap.val(current_coop.shares_euros); subs_cap.val(current_coop.shares_euros);
if (m_barcode.length > 0) m_barcode.val(current_coop.m_barcode); if (m_barcode.length > 0) m_barcode.val(current_coop.m_barcode);
if (sex.length > 0) { if (sex.length > 0) {
...@@ -497,6 +570,41 @@ $('#coop_create').submit(store_new_coop); ...@@ -497,6 +570,41 @@ $('#coop_create').submit(store_new_coop);
$('#generate_email').click(generate_email); $('#generate_email').click(generate_email);
$('#odoo_user_connect').click(); $('#odoo_user_connect').click();
$('#add_binome').click(function() {
if ($('#associate_area').is(':visible')) {
$('#associate_area').hide();
associated_old_choice = null;
$('#new_member_input').val('');
if (current_coop !=null) {
delete current_coop.parent_name;
delete current_coop.parent_id;
delete current_coop.is_associated_people;
delete current_coop.shift_template;
}
}
else {
$('#associate_area').show();
$('.member_choice').removeClass('choice_active');
$('#existing_member_choice_action').hide();
$('#new_member_choice_action').hide();
associated_old_choice = null;
}
});
$('.member_choice').on('click', function() {
if (associated_old_choice !=null && associated_old_choice!=$(this).attr('id')) {
$('#'+$(this).attr('id')+'_action').show();
$('#'+associated_old_choice+'_action').hide();
$('#'+associated_old_choice).removeClass('choice_active');
} else if (associated_old_choice ==null) {
$('#'+$(this).attr('id')+'_action').show();
}
associated_old_choice=$(this).attr('id');
$(this).addClass('choice_active');
});
$('#shift_calendar').click(show_shift_calendar); $('#shift_calendar').click(show_shift_calendar);
...@@ -516,3 +624,102 @@ payment_meaning.change(function() { ...@@ -516,3 +624,102 @@ payment_meaning.change(function() {
window.addEventListener("beforeunload", keep_in_process_work); window.addEventListener("beforeunload", keep_in_process_work);
empty_waiting_local_processes(); empty_waiting_local_processes();
/**
* Display the members from the search result
*/
function display_possible_members() {
$('.search_member_results_area').show();
$('.search_member_results').empty();
$('.btn_possible_member').off();
$('.chosen_associate').html("");
$('.chosen_associate_area').hide();
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_associate = member;
var member_button = '<div member_id="' + member.id + '">' + member.barcode_base + ' - ' + member.name + '</button>';
$('.chosen_associate').html(member_button);
$('.chosen_associate_area').show();
$('.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() {
retrieve_and_draw_shift_tempates();
// Set action to search for the member
$('#search_member_button').on('click', function() {
let search_str = $('#search_member_input').val();
if (search_str) {
$.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"
});
}
});
}
else {
members_search_results = [];
display_possible_members();
}
});
});
...@@ -32,6 +32,15 @@ function display_current_coop_form() { ...@@ -32,6 +32,15 @@ function display_current_coop_form() {
let street2_input = form.find('[name="street2"]'), let street2_input = form.find('[name="street2"]'),
phone_input = form.find('[name="phone"]'); phone_input = form.find('[name="phone"]');
if (current_coop.parent_name) {
$('#associated_member').show();
if (current_coop.parent_id)
$('#associated_member_name').text(current_coop.parent_name);
else $('#associated_member_name').text(current_coop.parent_name + " ATTENTION à faire manuellement");
} else {
$('#associated_member').hide();
}
chgt_shift_btn.hide(); chgt_shift_btn.hide();
chgt_shift_btn.off('click', open_shift_choice); chgt_shift_btn.off('click', open_shift_choice);
form.find('[name="firstname"]').val(current_coop.firstname); form.find('[name="firstname"]').val(current_coop.firstname);
......
...@@ -31,6 +31,7 @@ urlpatterns = [ ...@@ -31,6 +31,7 @@ urlpatterns = [
url(r'^latest_coop_id/$', views.latest_coop_id), url(r'^latest_coop_id/$', views.latest_coop_id),
url(r'^get/([0-9]+)$', views.get), url(r'^get/([0-9]+)$', views.get),
url(r'^exists/([a-zA-Z0-9_\-\.\+@]+)$', views.exists), url(r'^exists/([a-zA-Z0-9_\-\.\+@]+)$', views.exists),
url(r'^is_associated/([0-9]+)$', views.is_associated),
url(r'^get_couchdb_odoo_markers/(.+)$', views.get_couchdb_odoo_markers), url(r'^get_couchdb_odoo_markers/(.+)$', views.get_couchdb_odoo_markers),
url(r'^menu/$', views.menu), url(r'^menu/$', views.menu),
url(r'^verify_final_state$', views.verify_final_state), url(r'^verify_final_state$', views.verify_final_state),
......
...@@ -63,6 +63,10 @@ def exists(request, mail): ...@@ -63,6 +63,10 @@ def exists(request, mail):
answer = CagetteMember.exists(mail) answer = CagetteMember.exists(mail)
return JsonResponse({'answer': answer}) return JsonResponse({'answer': answer})
def is_associated(request, id_parent):
answer = CagetteMember.is_associated(id_parent)
return JsonResponse({'answer': answer})
def getmemberimage(request, id): def getmemberimage(request, id):
m = CagetteMember(id) m = CagetteMember(id)
call_res = m.get_image() call_res = m.get_image()
...@@ -97,7 +101,9 @@ def inscriptions(request, type=1): ...@@ -97,7 +101,9 @@ def inscriptions(request, type=1):
'POUCHDB_VERSION': getattr(settings, 'POUCHDB_VERSION', ''), 'POUCHDB_VERSION': getattr(settings, 'POUCHDB_VERSION', ''),
'max_chq_nb': getattr(settings, 'MAX_CHQ_NB', 12), 'max_chq_nb': getattr(settings, 'MAX_CHQ_NB', 12),
'show_ftop_button': getattr(settings, 'SHOW_FTOP_BUTTON', True), 'show_ftop_button': getattr(settings, 'SHOW_FTOP_BUTTON', True),
'db': settings.COUCHDB['dbs']['member']} 'db': settings.COUCHDB['dbs']['member'],
'ASSOCIATE_MEMBER_SHIFT' : getattr(settings, 'ASSOCIATE_MEMBER_SHIFT', '')
}
response = HttpResponse(template.render(context, request)) response = HttpResponse(template.render(context, request))
return response return response
......
...@@ -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 {
......
...@@ -92,6 +92,14 @@ ...@@ -92,6 +92,14 @@
margin: 1rem 0; margin: 1rem 0;
} }
.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 */
...@@ -115,6 +123,21 @@ ...@@ -115,6 +123,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;
......
...@@ -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;
......
...@@ -2,6 +2,8 @@ var calendar = null, ...@@ -2,6 +2,8 @@ var calendar = null,
selected_shift = null, selected_shift = null,
vw = null; vw = null;
/* - Logic */
/** /**
* A partner can exchange shifts if: * A partner can exchange shifts if:
* - s.he doesn't have to choose a makeup shift * - s.he doesn't have to choose a makeup shift
...@@ -23,6 +25,8 @@ function should_select_makeup() { ...@@ -23,6 +25,8 @@ function should_select_makeup() {
return partner_data.makeups_to_do > 0 || (partner_data.makeups_to_do > 0 && partner_data.is_associated_people === "True" && block_actions_for_attached_people === "False"); return partner_data.makeups_to_do > 0 || (partner_data.makeups_to_do > 0 && partner_data.is_associated_people === "True" && block_actions_for_attached_people === "False");
} }
/* - Server requests */
/** /**
* Proceed to shift exchange or registration * Proceed to shift exchange or registration
* @param {int} new_shift_id * @param {int} new_shift_id
...@@ -118,6 +122,7 @@ function add_or_change_shift(new_shift_id) { ...@@ -118,6 +122,7 @@ function add_or_change_shift(new_shift_id) {
`Si tu ne peux vraiment pas venir, tu seras noté.e absent.e à ton service. ` + `Si tu ne peux vraiment pas venir, tu seras noté.e absent.e à ton service. ` +
`Tu devras alors sélectionner un service de rattrapage sur ton espace membre.`); `Tu devras alors sélectionner un service de rattrapage sur ton espace membre.`);
} else if (error.status === 500 && error.msg === "Fail to create shift") { } else if (error.status === 500 && error.msg === "Fail to create shift") {
// TODO differentiate error cases!
alert(`Une erreur est survenue. ` + alert(`Une erreur est survenue. ` +
`Il est néanmoins possible que la requête ait abouti, ` + `Il est néanmoins possible que la requête ait abouti, ` +
`veuillez patienter quelques secondes puis vérifier vos services enregistrés.`); `veuillez patienter quelques secondes puis vérifier vos services enregistrés.`);
...@@ -139,8 +144,147 @@ function add_or_change_shift(new_shift_id) { ...@@ -139,8 +144,147 @@ function add_or_change_shift(new_shift_id) {
} }
}); });
} }
return null;
}
/**
* Send request to delete (cancel) a shift registration.
* @param {Int} shift_registration_id shift registration to cancel
*/
function delete_shift_registration(shift_registration_id) {
if (is_time_to('delete_shift_registration')) {
openModal();
tData = 'idPartner=' + partner_data.concerned_partner_id
+ '&idRegister=' + shift_registration_id
+ '&extra_shift_done=' + partner_data.extra_shift_done;
if (partner_data.is_associated_people === "False") {
tData += '&verif_token=' + partner_data.verif_token;
} else if (partner_data.is_associated_people === "True" && block_actions_for_attached_people === "False") {
tData += '&verif_token=' + partner_data.parent_verif_token;
} else {
return false;
}
$.ajax({
type: 'POST',
url: "/shifts/cancel_shift",
dataType:"json",
data: tData,
timeout: 3000,
success: function() {
partner_data.extra_shift_done -= 1;
// Refetch partner shifts list & update DOM
load_partner_shifts(partner_data.concerned_partner_id)
.then(() => {
init_shifts_list();
if (partner_data.extra_shift_done > 0) {
$(".extra_shift_done").text(partner_data.extra_shift_done);
init_delete_registration_buttons();
} else {
$("#can_delete_future_registrations_area").hide();
$(".delete_registration_button").off();
$(".delete_registration_button").hide();
}
closeModal();
setTimeout(() => {
alert("La présence a bien été annulée !");
}, 100);
});
// Redraw calendar
calendar.refetchEvents();
},
error: function() {
closeModal();
alert("Une erreur est survenue.");
}
});
}
return null;
}
/**
* Proceed affecting a shift registration to a/both member(s) of a pair
* @param {string} partner
* @param {string} shift_id
*/
function affect_shift(partner, shift_id) {
if (is_time_to('affect_shift')) {
tData = 'idShiftRegistration=' + shift_id
+'&idPartner=' + partner_data.partner_id
+ '&affected_partner=' + partner
+ '&verif_token=' + partner_data.verif_token;
tUrl = '/shifts/affect_shift';
$.ajax({
type: 'POST',
url: tUrl,
dataType:"json",
data: tData,
timeout: 3000,
success: function() {
load_partner_shifts(partner_data.concerned_partner_id)
.then(() => {
init_shifts_list();
modal.find(".btn-modal-ok").show();
closeModal();
});
},
error: function() {
init_shifts_list();
modal.find(".btn-modal-ok").show();
closeModal();
alert(`Une erreur est survenue. ` +
`Il est néanmoins possible que la requête ait abouti, ` +
`veuillez patienter quelques secondes puis vérifier vos services enregistrés.`);
}
});
}
}
/**
* Reset a member extra_shift_done to 0
*/
function offer_extra_shift() {
if (is_time_to('offer_extra_shift')) {
openModal();
$.ajax({
type: 'POST',
url: "/members_space/offer_extra_shift",
dataType:"json",
data: {
partner_id: partner_data.concerned_partner_id
},
timeout: 3000,
success: function() {
$("#can_delete_future_registrations_area").hide();
$(".delete_registration_button").off();
$(".delete_registration_button").hide();
closeModal();
alert("Don de service effectué");
},
error: function() {
closeModal();
alert("Une erreur est survenue");
}
});
}
} }
/* - DOM */
function init_shifts_list() { function init_shifts_list() {
$(".loading-incoming-shifts").hide(); $(".loading-incoming-shifts").hide();
$("#shifts_list").show(); $("#shifts_list").show();
...@@ -150,7 +294,7 @@ function init_shifts_list() { ...@@ -150,7 +294,7 @@ function init_shifts_list() {
} else { } else {
$("#shifts_list").empty(); $("#shifts_list").empty();
for (shift of incoming_shifts) { for (let shift of incoming_shifts) {
let shift_line_template = $("#selectable_shift_line_template"); let shift_line_template = $("#selectable_shift_line_template");
let datetime_shift_start = new Date(shift.date_begin.replace(/\s/, 'T')); let datetime_shift_start = new Date(shift.date_begin.replace(/\s/, 'T'));
...@@ -161,6 +305,7 @@ function init_shifts_list() { ...@@ -161,6 +305,7 @@ function init_shifts_list() {
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));
// Disable or not
if (!can_exchange_shifts() && block_actions_for_attached_people === "True") { if (!can_exchange_shifts() && block_actions_for_attached_people === "True") {
shift_line_template.find(".selectable_shift_line").removeClass("btn--primary"); shift_line_template.find(".selectable_shift_line").removeClass("btn--primary");
shift_line_template.find(".selectable_shift_line").addClass("btn"); shift_line_template.find(".selectable_shift_line").addClass("btn");
...@@ -172,10 +317,12 @@ function init_shifts_list() { ...@@ -172,10 +317,12 @@ function init_shifts_list() {
shift_line_template.find(".checkbox").prop("value", shift.id); shift_line_template.find(".checkbox").prop("value", shift.id);
} }
// Set assign shift button
if (partner_data.associated_partner_id === "False" && partner_data.parent_id === "False") { if (partner_data.associated_partner_id === "False" && partner_data.parent_id === "False") {
shift_line_template.find('.affect_associate_registered').hide(); shift_line_template.find('.affect_associate_registered').hide();
} else { } else {
shift_line_template.find('.affect_associate_registered').attr('id', 'shift_id_'+shift.id); shift_line_template.find('.affect_associate_registered').closest(".shift_line_container")
.attr('id', 'shift_id_'+shift.id);
if (shift.associate_registered==="both") { if (shift.associate_registered==="both") {
shift_line_template.find('.affect_associate_registered').text("Les deux"); shift_line_template.find('.affect_associate_registered').text("Les deux");
shift_line_template.find('.affect_associate_registered').addClass('btn--success'); shift_line_template.find('.affect_associate_registered').addClass('btn--success');
...@@ -200,6 +347,17 @@ function init_shifts_list() { ...@@ -200,6 +347,17 @@ function init_shifts_list() {
} }
} }
// Set delete registration button if shift isn't a makeup
if (partner_data.extra_shift_done > 0 && shift.is_makeup === false) {
if (shift_line_template.find(".delete_registration_button").length === 0) {
let delete_reg_button_template = $("#delete_registration_button_template");
shift_line_template.find(".shift_line_container").append(delete_reg_button_template.html());
}
} else {
shift_line_template.find(".delete_registration_button").remove();
}
$("#shifts_list").append(shift_line_template.html()); $("#shifts_list").append(shift_line_template.html());
shift_line_template.find('.affect_associate_registered').removeClass('btn--danger'); shift_line_template.find('.affect_associate_registered').removeClass('btn--danger');
shift_line_template.find('.affect_associate_registered').removeClass('btn--success'); shift_line_template.find('.affect_associate_registered').removeClass('btn--success');
...@@ -234,7 +392,8 @@ function init_shifts_list() { ...@@ -234,7 +392,8 @@ function init_shifts_list() {
$(".affect_associate_registered").on("click", function() { $(".affect_associate_registered").on("click", function() {
// Display modal // Display modal
id = $(this).attr('id') let id = $(this).closest(".shift_line_container")
.attr('id')
.split('_')[2]; .split('_')[2];
let modal_template = $("#modal_affect_shift"); let modal_template = $("#modal_affect_shift");
...@@ -273,48 +432,6 @@ function init_shifts_list() { ...@@ -273,48 +432,6 @@ function init_shifts_list() {
} }
} }
/**
* Proceed to shift modification
* @param {string} partner
* @param {string} shift_id
*/
function affect_shift(partner, shift_id) {
tData = 'idShiftRegistration=' + shift_id
+'&idPartner=' + partner_data.partner_id
+ '&affected_partner=' + partner
+ '&verif_token=' + partner_data.verif_token;
tUrl = '/shifts/affect_shift';
$.ajax({
type: 'POST',
url: tUrl,
dataType:"json",
data: tData,
timeout: 3000,
success: function() {
load_partner_shifts(partner_data.concerned_partner_id)
.then(() => {
init_shifts_list();
modal.find(".btn-modal-ok").show();
closeModal();
});
},
error: function() {
init_shifts_list();
modal.find(".btn-modal-ok").show();
closeModal();
alert(`Une erreur est survenue. ` +
`Il est néanmoins possible que la requête ait abouti, ` +
`veuillez patienter quelques secondes puis vérifier vos services enregistrés.`);
}
});
}
/** /**
* Inits the page when the calendar is displayed * Inits the page when the calendar is displayed
*/ */
...@@ -351,6 +468,22 @@ function init_calendar_page() { ...@@ -351,6 +468,22 @@ function init_calendar_page() {
$("#need_to_select_makeups_message").show(); $("#need_to_select_makeups_message").show();
} }
if (partner_data.extra_shift_done > 0) {
$(".extra_shift_done").text(partner_data.extra_shift_done);
$("#can_delete_future_registrations_area").show();
$("#offer_extra_shift").on("click", () => {
openModal(
"<p>Je ne souhaite pas supprimer un service futur.</p>",
offer_extra_shift,
"Confirmer",
false
);
});
$("#delete_future_registration").on("click", init_delete_registration_buttons);
}
let default_initial_view = ""; let default_initial_view = "";
let header_toolbar = {}; let header_toolbar = {};
...@@ -575,6 +708,30 @@ function init_read_only_calendar_page() { ...@@ -575,6 +708,30 @@ function init_read_only_calendar_page() {
calendar.render(); calendar.render();
} }
function init_delete_registration_buttons() {
$(".delete_registration_button").off();
$(".delete_registration_button").on("click", function() {
let shift_name = $(this).closest("div")
.siblings(".selectable_shift_line")
.text()
.trim();
let shift_id = $(this).closest(".shift_line_container")
.attr('id')
.split('_')[2];
openModal(
`<p>Je m'apprête supprimer ma présence au service du <b>${shift_name}</b></p>`,
() => {
delete_shift_registration(shift_id);
},
"Confirmer",
false
);
});
$(".delete_registration_button").css('display', 'flex');
}
function init_shifts_exchange() { function init_shifts_exchange() {
$(".shifts_exchange_page_content").hide(); $(".shifts_exchange_page_content").hide();
vw = window.innerWidth; vw = window.innerWidth;
...@@ -636,7 +793,17 @@ function init_shifts_exchange() { ...@@ -636,7 +793,17 @@ function init_shifts_exchange() {
} }
$(window).smartresize(function() { $(window).smartresize(function() {
// only apply if a width threshold is passed
if (
vw > 992 && window.innerWidth <= 992 ||
vw <= 992 && window.innerWidth > 992 ||
vw > 768 && window.innerWidth <= 768 ||
vw <= 768 && window.innerWidth > 768
) {
vw = window.innerWidth; vw = window.innerWidth;
init_calendar_page(); init_calendar_page();
} else {
vw = window.innerWidth;
}
}); });
} }
...@@ -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
...@@ -235,3 +236,12 @@ def get_shifts_history(request): ...@@ -235,3 +236,12 @@ def get_shifts_history(request):
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)
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)
...@@ -129,6 +129,10 @@ ...@@ -129,6 +129,10 @@
La Cagette use False to implement custom rules La Cagette use False to implement custom rules
- ASSOCIATE_MEMBER_SHIFT = ''
Id number of the associate shift template
### Scales and labels files generation ### Scales and labels files generation
- DAV_PATH = '/data/dav/cagette' - DAV_PATH = '/data/dav/cagette'
......
...@@ -35,14 +35,15 @@ function get_shift_name(s_data) { ...@@ -35,14 +35,15 @@ function get_shift_name(s_data) {
if (s_data && s_data.week) { if (s_data && s_data.week) {
shift_name = weeks_name[s_data.week]; shift_name = weeks_name[s_data.week];
if (s_data.type == 2 && typeof manage_ftop != "undefined" && manage_ftop == true) { if (s_data.type == 2 && typeof manage_ftop != "undefined" && manage_ftop == true && s_data.id != ASSOCIATE_MEMBER_SHIFT) {
shift_name = 'Volant'; shift_name = 'Volant';
} else if(s_data.id == ASSOCIATE_MEMBER_SHIFT) {
shift_name = 'Binôme';
} else { } else {
shift_name += s_data.day + ' - ' + s_data.begin; shift_name += s_data.day + ' - ' + s_data.begin;
shift_name += ' - ' + s_data.place; shift_name += ' - ' + s_data.place;
} }
} }
return shift_name; return shift_name;
} }
......
...@@ -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:
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
<section class="center" id="new_coop"> <section class="center" id="new_coop">
<div class="grid-1"> <div class="grid-1">
<div class="item-center"> <div class="">
<h2 class="title"> <h2 class="title">
NOUVEAU MEMBRE NOUVEAU MEMBRE
</h2> </h2>
...@@ -65,14 +65,55 @@ ...@@ -65,14 +65,55 @@
<input type="number" min="1" placeholder="Nb de chèques" name="ch_qty" id="ch_qty" style="display:none;"/> <input type="number" min="1" placeholder="Nb de chèques" name="ch_qty" id="ch_qty" style="display:none;"/>
</p> </p>
{% if input_barcode %} {% if input_barcode %}
<p> <p>
<input type="text" name="m_barcode" id="m_barcode" maxlength="13" size="13" placeholder="Code barre" autocomplete="off" required/> <input type="text" name="m_barcode" id="m_barcode" maxlength="13" size="13" placeholder="Code barre" autocomplete="off" required/>
</p> </p>
{% endif %} {% endif %}
{% if ASSOCIATE_MEMBER_SHIFT %}
<p id="add_binome" >+ Binomes (facultatif)</p>
<div id="associate_area" style="display:none;">
<div class="choice_button_area d-flex" >
<div id="existing_member_choice" class="member_choice">
A mettre en binome avec un.e membre existant.e
</div>
<div id="new_member_choice" class="member_choice">
A mettre en binome avec un.e nouveau membre
</div>
</div>
<div id="existing_member_choice_action" style="display:none;">
<input type="text" id="search_member_input" value="" placeholder="Nom ou numéro du coop..." >
<div class="btn--primary" id="search_member_button">Recherche</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 class="chosen_associate_area" style="display:none;">
<div >
<p><i>Binôme choisit : </i></p>
</div>
<div class="chosen_associate"></div>
</div>
</div>
<div id="new_member_choice_action" style="display:none;">
<div >
<div>
<input type="text" id="new_member_input" value="" placeholder="Nom du membre" >
</div>
</div>
</div>
</div>
{% endif %}
<div>
<button class="btn--primary">Valider</button> <button class="btn--primary">Valider</button>
</form>
</div> </div>
</form>
<div id="mail_generation"> <div id="mail_generation">
(*) L'adresse mail étant obligatoire, si le nouveau membre n'en a pas, veuillez en créer une en cliquant sur le bouton suivant : <a class="btn--info" id="generate_email">+</a> (*) L'adresse mail étant obligatoire, si le nouveau membre n'en a pas, veuillez en créer une en cliquant sur le bouton suivant : <a class="btn--info" id="generate_email">+</a>
</div> </div>
...@@ -119,6 +160,7 @@ ...@@ -119,6 +160,7 @@
var couchdb_dbname = '{{db}}'; var couchdb_dbname = '{{db}}';
var couchdb_server = '{{couchdb_server}}' + couchdb_dbname; var couchdb_server = '{{couchdb_server}}' + couchdb_dbname;
var dbc = new PouchDB(couchdb_dbname); var dbc = new PouchDB(couchdb_dbname);
var ASSOCIATE_MEMBER_SHIFT = '{{ASSOCIATE_MEMBER_SHIFT}}';
var sync = PouchDB.sync(couchdb_dbname, couchdb_server, { var sync = PouchDB.sync(couchdb_dbname, couchdb_server, {
live: true, live: true,
retry: true, retry: true,
......
...@@ -60,6 +60,9 @@ ...@@ -60,6 +60,9 @@
<input type="text" name="m_barcode" id="m_barcode" disabled/> <input type="text" name="m_barcode" id="m_barcode" disabled/>
</p> </p>
{% endif %} {% endif %}
<div id="associated_member">
En binôme avec : <span id ="associated_member_name"></span>
</div>
</div> </div>
<p class="buttons"> <p class="buttons">
<button class="btn--success" name="valider">Tout est bon</button> <button class="btn--success" name="valider">Tout est bon</button>
......
...@@ -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,7 +36,7 @@ ...@@ -36,7 +36,7 @@
</div> </div>
<div id="selectable_shift_line_template"> <div id="selectable_shift_line_template">
<div class="d-flex selectable_shift"> <div class="d-flex shift_line_container selectable_shift">
<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">
...@@ -49,6 +49,10 @@ ...@@ -49,6 +49,10 @@
</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>
<div id="shift_partner" class="btn--primary"> <div id="shift_partner" class="btn--primary">
...@@ -58,7 +62,6 @@ ...@@ -58,7 +62,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 +143,8 @@ ...@@ -140,7 +143,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