Commit eb1e61d0 by Damien Moulard

Merge branch 'adaptation_supercoop_supercafoutch' into 'dev_cooperatic'

Adaptation supercoop supercafoutch

See merge request !196
parents c805631f dba4831f
Pipeline #2399 passed with stage
in 1 minute 23 seconds
......@@ -90,16 +90,19 @@ class CagetteInventory(models.Model):
p[k] = ''
# Get shelf sortorder
if p['shelf_id'] is not False:
if p['shelf_id'] is not False and len(p['shelf_id']) > 0:
c = [['id', '=', p['shelf_id'][0]]]
f = ['id', 'sort_order']
res_sortorder = api.search_read('product.shelfs', c, f)
if res_sortorder:
p['shelf_sortorder'] = res_sortorder[0]['sort_order']
else:
p['shelf_sortorder'] = ''
res['data'] = pdts
except Exception as e:
coop_logger.error("get_custom_list_products -> Erreur lors de la récupération des produits : %s", str(e))
res['error'] = "Erreur lors de la récupération des produits (" + str(e) + ")"
return res
......
......@@ -5,7 +5,7 @@ from outils.common import OdooAPI
from members.models import CagetteUser
from members.models import CagetteMembers
from members.models import CagetteMember
from members.models import CagetteServices
from shifts.models import CagetteServices
from shifts.models import CagetteShift
from outils.common import MConfig
from datetime import datetime
......@@ -313,7 +313,8 @@ def admin(request):
""" Administration des membres """
template = loader.get_template('members/admin/index.html')
context = {'title': 'BDM',
'module': 'Membres'}
'module': 'Membres',
'admin_binome_active': getattr(settings, 'ADMIN_BINOME_ACTIVE', True),}
return HttpResponse(template.render(context, request))
def manage_makeups(request):
......@@ -494,14 +495,19 @@ def shift_subscription(request):
and delete all existing shifts EXCEPT makeups.
"""
res = {}
if CagetteUser.are_credentials_ok(request):
data = json.loads(request.body.decode())
data = json.loads(request.body.decode())
partner_id = int(data["partner_id"])
is_allowed = CagetteUser.are_credentials_ok(request)
if is_allowed is False:
credentials = CagetteMember.get_credentials(request, with_id = True)
if 'success' in credentials and credentials['success'] is True and credentials['id'] == partner_id:
is_allowed = True
if is_allowed is True:
partner_id = int(data["partner_id"])
shift_type = data["shift_type"]
if shift_type == 1:
# 1 = standard
shift_template_id = data["shift_template_id"]
shift_template_id = int(data["shift_template_id"])
else:
# 2 = ftop
......@@ -529,7 +535,6 @@ def shift_subscription(request):
)
res["unsubscribe_member"] = m.unsubscribe_member(changing_shift = True)
m.create_coop_shift_subscription(shift_template_id, shift_type)
# Return necessary data
......
......@@ -49,6 +49,7 @@ h1 .member_name {font-weight: bold;}
.members_list li.btn--inverse.late {background-color: #de9b00; color: white}
.members_list li.btn--inverse.both {background-color: #0275d8 ; color: white}
.members_list.done li.btn {pointer-events: none;}
#service_entry_success {font-size: x-large;}
#service_entry_success .explanations {margin: 25px 0; font-size: 18px;}
#service_entry_success .points,
......
......@@ -284,7 +284,7 @@ function create_pair(payload) {
data.responseJSON.errors.map(function(error) {
message += ('\n' + error);
return null;
});
}
......
......@@ -293,7 +293,7 @@ $(document).ready(function() {
let search_str = $('#search_member_input').val();
$.ajax({
url: '/members/search/' + search_str,
url: `/members/search/${search_str}?search_type=shift_template_data`,
dataType : 'json',
success: function(data) {
$('#partner_data_area').hide();
......
......@@ -231,7 +231,7 @@ $(document).ready(function() {
let search_str = $('#search_member_input').val();
$.ajax({
url: '/members/search/' + search_str,
url: `/members/search/${search_str}?search_type=manage_shift_registrations`,
dataType : 'json',
success: function(data) {
members_search_results = [];
......
......@@ -92,12 +92,12 @@ function new_coop_validation() {
coop_registration_details.find('.shift_template').text(st);
process_state.html(current_coop.firstname + ' ' +current_coop.lastname);
coop_registration_details.find("#parentName").text("")
coop_registration_details.find("#parent").attr("hidden", true)
coop_registration_details.find("#parentName").text("");
coop_registration_details.find("#parent").attr("hidden", true);
if (current_coop.parent_name !== undefined) {
coop_registration_details.find("#parentName").text(current_coop.parent_name)
coop_registration_details.find("#parent").removeAttr("hidden")
coop_registration_details.find("#parentName").text(current_coop.parent_name);
coop_registration_details.find("#parent").removeAttr("hidden");
}
if (current_coop.shift_template.data && current_coop.shift_template.data.id != ASSOCIATE_MEMBER_SHIFT) {
......@@ -126,7 +126,7 @@ function create_new_coop() {
$('.chosen_associate').html("");
$('.chosen_associate_area').hide();
$('.member_choice').removeClass('choice_active');
$(".remove_binome_icon").on("click", hide_chosen_associate)
$(".remove_binome_icon").on("click", hide_chosen_associate);
local_in_process = getLocalInProcess();
if (getLocalInProcess().length > 0) {
empty_waiting_local_processes();
......@@ -271,11 +271,13 @@ function store_new_coop(event) {
if (active_asso_area.length > 0) {
// If user click as if a "binôme" is beeing created, data about parent member must exist
let associated_data_ok = false;
if (
($(active_asso_area[0]).attr('id') === "new_member_choice" && $('#new_member_input').val().trim().length > 0)
($(active_asso_area[0]).attr('id') === "new_member_choice" && $('#new_member_input').val()
.trim().length > 0)
||
($(active_asso_area[0]).attr('id') === "existing_member_choice" && $('#existing_member_choice_action .chosen_associate div.member').length > 0)
) {
) {
associated_data_ok = true;
}
if (associated_data_ok === false) errors.push("Le membre 'titulaire' du binôme n'est pas défini");
......@@ -318,7 +320,7 @@ function store_new_coop(event) {
}
}
});
}
}
......@@ -361,6 +363,7 @@ function modify_current_coop() {
$('#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';
......@@ -726,7 +729,7 @@ function display_possible_members() {
/**
* Search for members to associate a new member with an old one.
* Search for members to associate a new member with an old one.
*/
function searchMembersForAssociate() {
let search_str = $('#search_member_input').val();
......
......@@ -41,6 +41,7 @@ var coop_info = $('.coop-info');
var service_data = null;
const missed_begin_msg = $('#missed_begin_msg').html();
const current_shift_process_data_actions = $('#current_shift_process_data_actions');
let no_pict_msg = $('#no-picture-msg');
......@@ -70,6 +71,12 @@ var html_elts = {
var chars = []; //input chars buffer
var reset_shift_process_actions_zone = function() {
current_shift_process_data_actions.off('click', 'a');
current_shift_process_data_actions.hide();
current_shift_process_data_actions.empty();
};
function fill_member_slide(member) {
no_pict_msg.hide();
current_displayed_member = member;
......@@ -282,6 +289,9 @@ function fill_service_entry(s) {
// if (typeof s.late != "undefined" && s.late == true) {
// m_list = '<ul class="members_list late">';
// }
if (s.state == 'done') {
m_list = '<ul class="members_list done">';
}
$.each(s.members, function(i, e) {
var li_class = "btn";
var li_data = "";
......@@ -304,6 +314,9 @@ function fill_service_entry(s) {
} else {
li_data = ' data-rid="'+e.id+'" data-mid="'+e.partner_id[0]+'"';
}
if (s.state == 'done') {
li_data += ' disabled ';
}
m_list += '<li class="'+li_class+'" '+li_data+'>';
m_list += e.partner_id[1];
m_list += '</li>';
......@@ -311,6 +324,46 @@ function fill_service_entry(s) {
m_list += '</ul>';
}
if (coop_is_connected()) {
// Add shift process data
reset_shift_process_actions_zone();
if (s.state == 'draft' || s.state == 'confirm') {
let btn = $('<a>').addClass('btn btn--primary txtcenter')
.text('Enregistrer les absences / présences')
.attr('id', 'record_shift_absences');
current_shift_process_data_actions.append(btn);
current_shift_process_data_actions.on('click', '#record_shift_absences', function() {
msg = "<p>Lancer le traitement des présences et absences de ce service</p>";
openModal(msg, function() {
btn.attr('disabled', 'true');
try {
$.ajax({
url: '/members/record_shift_absences/' + s.id,
dataType : 'json'
})
.done(function(rData) {
if (typeof rData.res.update !== "undefined" && rData.res.update == true) {
enqueue_message_for_next_loading("Données de présences traitées.");
location.reload();
} else {
closeModal();
btn.removeAttr('disabled');
alert(JSON.stringify(rData.res));
}
});
} catch (e) {
console.log(e);
}
}, 'Confirmer');
});
} else {
current_shift_process_data_actions.append("<em>Traitement des présences : " + s.state + "</em>");
}
current_shift_process_data_actions.show();
}
rattrapage_ou_volant = null;
shift_members.html(m_list);
rattrapage_wanted.show();
......@@ -401,6 +454,8 @@ function get_service_entry_data() {
})
.done(function(rData) {
info_place.text('');
reset_shift_process_actions_zone();
var page_title = pages.service_entry.find('h1');
page_title.text('Qui es-tu ?');
......
......@@ -43,6 +43,7 @@ urlpatterns = [
url(r'^services_at_time/([0-9TZ\-\: \.]+)/([0-9\-]+)$', views.services_at_time),
url(r'^service_presence/$', views.record_service_presence),
url(r'^record_absences/?([0-9\-\ \:]*)$', views.record_absences),
url(r'^record_shift_absences/?([0-9]+)$', views.record_shift_absences),
url(r'^close_ftop_service$', views.close_ftop_service),
url(r'^get_credentials$', views.get_credentials),
url(r'^remove_data_from_couchdb$', views.remove_data_from_CouchDB),
......
......@@ -5,7 +5,7 @@ from outils.for_view_imports import *
from members.models import CagetteMember
from members.models import CagetteUser
from members.models import CagetteMembers
from members.models import CagetteServices
from shifts.models import CagetteServices, CagetteService
from outils.forms import GenericExportMonthForm
import datetime
......@@ -105,6 +105,7 @@ def inscriptions(request, type=1):
'show_ftop_button': getattr(settings, 'SHOW_FTOP_BUTTON', True),
'db': settings.COUCHDB['dbs']['member'],
'ASSOCIATE_MEMBER_SHIFT' : getattr(settings, 'ASSOCIATE_MEMBER_SHIFT', ''),
'can_create_binome': getattr(settings, 'CAN_CREATE_BINOME', True),
'prepa_odoo_url' : getattr(settings, 'PREPA_ODOO_URL', '/members/prepa-odoo'),
'committees_shift_id': committees_shift_id,
}
......@@ -347,6 +348,10 @@ def easy_validate_shift_presence(request):
def record_absences(request, date):
return JsonResponse({'res': CagetteServices.record_absences(date)})
def record_shift_absences(request, id):
shift = CagetteService(id)
return JsonResponse({'res': shift.record_absences(request)})
def close_ftop_service(request):
"""Close the closest past FTOP service"""
return JsonResponse({'res': CagetteServices.close_ftop_service()})
......
from django.db import models
from outils.common_imports import *
from members.models import CagetteServices
from shifts.models import CagetteServices
from outils.common import OdooAPI
......
......@@ -39,6 +39,7 @@
justify-content: space-between;
}
@media screen and (max-width:992px) {
#calendar_top_info {
display: flex;
......
var calendar = null;
function init_my_shifts_tile() {
if (incoming_shifts.length === 0) {
$("#home_tile_my_services #home_incoming_services").text("Aucun service à venir...");
......@@ -20,6 +22,97 @@ function init_my_shifts_tile() {
}
}
function process_asked_shift_template_change(shift_t_id) {
var s_data = shift_templates[shift_t_id].data;
var shift_name = get_shift_name(s_data);
let msg = 'Inscription au créneau ' + shift_name;
openModal(
msg,
function() {
setTimeout(openModal, 300); // to show something happened , work in process
let data = {
partner_id: parseInt(partner_data.partner_id, 10),
shift_type: 1, //force to standard
shift_template_id: shift_t_id,
unsubscribe_first: true
};
$.ajax({
type: 'POST',
url: '/members/shift_subscription',
data: JSON.stringify(data),
dataType:"json",
traditional: true,
contentType: "application/json; charset=utf-8",
success: function(data) {
stdata = data.shift_template;
partner_data.regular_shift_name = stdata.name;
partner_data.shift_type = "standard";
init_my_info_data();
location.reload();
},
error: function(err_data) {
if (
err_data.status == 409
&& typeof (err_data.responseJSON) != "undefined"
&& err_data.responseJSON.code === "makeup_found"
) {
let modal_template = $("#modal_error_change_shift_template");
modal_template.find(".shift_template_name").text(shift_template_name);
closeModal();
openModal(
modal_template.html(),
() => {},
"Compris !",
true,
false
);
} else {
err = {
msg: "erreur serveur lors de l'inscription du membre au créneau",
ctx: 'members_space.shift_subscrition'
};
report_JS_error(err, 'members_space');
closeModal();
$.notify("Une erreur est survenue lors de l'inscription au créneau.", {
globalPosition:"top right",
className: "error"
});
}
}
});
},
'Valider',
true, // modal closes after validation
true,
edit_shift_template_registration // on cancel , reload calendar
);
}
function edit_shift_template_registration() {
let external = true;
if (calendar == null) calendar = $('#modal-calendar-choice').clone();
if ($('#modal-calendar-choice').html().length > 0) {
$('#modal-calendar-choice').empty();
}
calendar.find('.oddeven_selector').empty();
displayMsg(calendar.html());
$('#week_types').find('input')
.change(() => {
filter_weeks(external);
});
retrieve_and_draw_shift_tempates(external);
}
function init_home() {
$("#go_to_shifts_calendar").on("click", () => {
goto('echange-de-services');
......@@ -37,6 +130,13 @@ function init_home() {
goto('faq');
});
$(".member_shift_name_area").on("click", ".fa-edit", (e) => {
$('#week_types').find('input')
.change(filter_weeks);
e.preventDefault();
edit_shift_template_registration();
});
if (partner_data.is_in_association === false) {
$("#home .member_associated_partner_area").hide();
} else {
......
var calendar = null,
selected_shift = null,
vw = null;
vw = null,
adding_mode = false;
/* - Logic */
......@@ -51,6 +52,9 @@ function add_or_change_shift(new_shift_id) {
if (selected_shift === null) {
tUrl = '/shifts/add_shift';
if (partner_data.makeups_to_do > 0) {
tData += '&is_makeup=1';
}
} else {
tUrl = '/shifts/change_shift';
tData = tData + '&idOldShift='+ selected_shift.shift_id[0] +'&idRegister=' + selected_shift.id;
......@@ -121,6 +125,11 @@ function add_or_change_shift(new_shift_id) {
`Afin de faciliter la logistique des services, il n'est plus possible de l'échanger. ` +
`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.`);
} else if (error.status === 400 && 'msg' in error.responseJSON && error.responseJSON.msg === "Not allowed to change shift") {
alert(`Désolé ! Le service que tu souhaites échanger démarre dans trop peu de temps. ` +
`Afin de faciliter la logistique des services, il n'est plus possible de l'échanger. ` +
`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.`);
} else if (error.status === 500 && 'msg' in error.responseJSON && error.responseJSON.msg === "Fail to create shift") {
// TODO differentiate error cases!
alert(`Une erreur est survenue. ` +
......@@ -143,6 +152,8 @@ function add_or_change_shift(new_shift_id) {
}, 300);
}
});
adding_mode = false;
$('#start_adding_shift').prop('disabled', false);
}
return null;
......@@ -269,7 +280,7 @@ function offer_extra_shift() {
timeout: 3000,
success: function() {
partner_data.extra_shift_done -= 1;
$("#can_delete_future_registrations_area").hide();
$(".delete_registration_button").off();
$(".delete_registration_button").hide();
......@@ -315,6 +326,7 @@ function init_shifts_list() {
if (!can_exchange_shifts()) {
shift_line_template.find(".selectable_shift_line").addClass("btn");
shift_line_template.find(".checkbox").prop("disabled", "disabled");
$('#start_adding_shift').prop('disabled', true);
} else {
if (shift.is_makeup==true) {
shift_line_template.find(".selectable_shift_line").addClass("btn--warning");
......@@ -577,12 +589,28 @@ function init_calendar_page() {
"Valider"
);
} else if (selected_shift === null && can_exchange_shifts()) {
/* could exchange shift but no old shift selected */
openModal(
"Je dois sélectionner un service à échanger.",
closeModal,
"J'ai compris"
);
if (adding_mode === false) {
/* could exchange shift but no old shift selected */
openModal(
"Je dois sélectionner un service à échanger.",
closeModal,
"J'ai compris"
);
} else {
// Display modal
let modal_template = $("#modal_add_shift_template");
modal_template.find(".date_new_shift").text(new_shift_date);
modal_template.find(".time_new_shift").text(new_shift_time);
openModal(
modal_template.html(),
() => {
add_or_change_shift(new_shift_id);
},
"Valider"
);
}
} else if (should_select_makeup()) {
/* choose a makeup service */
// Check if selected new shift is in less than 6 months
......@@ -730,14 +758,15 @@ function init_delete_registration_buttons() {
if (partner_data.extra_shift_done > 0) {
$(".delete_registration_button").on("click", function() {
let shift_name = $(this).closest("div")
.parent().parent()
.parent()
.parent()
.find(".shift_line_date")
.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>`,
() => {
......@@ -747,7 +776,7 @@ function init_delete_registration_buttons() {
false
);
});
$(".delete_registration_button").css('display', 'flex');
}
}
......@@ -811,6 +840,19 @@ function init_shifts_exchange() {
init_calendar_page();
}
$('#start_adding_shift').click((c) => {
openModal(
"<p>Je souhaite sélectionner un service supplémentaire.</p>",
() => {
$(c.target).prop('disabled', true);
adding_mode = true;
closeModal();
},
"Confirmer",
false
);
});
$(window).smartresize(function() {
// only apply if a width threshold is passed
if (
......
......@@ -314,6 +314,7 @@ $(document).ready(function() {
// For associated people, their parent name is attached in their display name
let partner_name_split = partner_data.name.split(', ');
partner_data.name = partner_name_split[partner_name_split.length - 1];
base_location = (app_env === 'dev') ? '/members_space/' : '/';
......
......@@ -29,7 +29,8 @@ def index(request, exception=None):
context = {
'title': 'Espace Membre',
'COMPANY_LOGO': getattr(settings, 'COMPANY_LOGO', None),
'block_actions_for_attached_people' : getattr(settings, 'BLOCK_ACTIONS_FOR_ATTACHED_PEOPLE', True)
'block_actions_for_attached_people' : getattr(settings, 'BLOCK_ACTIONS_FOR_ATTACHED_PEOPLE', True),
'permanent_message': getattr(settings, 'PERMANENT_MESSAGE_BELOW_CONNECTION_FIELDS', None),
}
template = loader.get_template('members_space/index.html')
......@@ -120,6 +121,7 @@ def index(request, exception=None):
m = CagetteMembersSpace()
context['show_faq'] = getattr(settings, 'MEMBERS_SPACE_FAQ_TEMPLATE', 'members_space/faq.html')
context['show_abcd_calendar'] = getattr(settings, 'SHOW_ABCD_CALENDAR_TAB', True)
partnerData["comite"] = m.is_comite(partner_id)
context['partnerData'] = partnerData
......@@ -130,6 +132,8 @@ def index(request, exception=None):
if hasattr(settings, 'SHIFT_EXCHANGE_DAYS_TO_HIDE'):
days_to_hide = settings.SHIFT_EXCHANGE_DAYS_TO_HIDE
context['daysToHide'] = days_to_hide
can_add_shift = getattr(settings, 'CAN_ADD_SHIFT', False)
context['canAddShift'] = "true" if can_add_shift is True else "false"
msettings = MConfig.get_settings('members')
context['forms_link'] = msettings['forms_link']['value'] if 'forms_link' in msettings else ''
......@@ -169,9 +173,20 @@ def home(request):
Consequently, the front-end url should be unknown from the server so the user is redirected to the index,
then the front-end index will call this endpoint to load the home page
"""
template = loader.get_template('members_space/home.html')
template = loader.get_template(getattr(settings, 'MEMBERS_SPACE_HOME_TEMPLATE', 'members_space/home.html'))
coop_can_change_shift_template = getattr(settings, 'COOP_CAN_CHANGE_SHIFT_TEMPLATE', False)
if coop_can_change_shift_template is True:
# make further investigation only if COOP_CAN_CHANGE_SHIFT_TEMPLATE is True
if 'id' in request.COOKIES:
partner_id = request.COOKIES['id']
cs = CagetteShift()
partnerData = cs.get_data_partner(partner_id)
if partnerData['cooperative_state'] == "unsubscribed":
coop_can_change_shift_template = False
context = {
'title': 'Espace Membres',
'coop_can_change_shift_template': coop_can_change_shift_template,
'max_begin_hour': settings.MAX_BEGIN_HOUR,
}
# Get messages to display
msettings = MConfig.get_settings('members')
......@@ -186,7 +201,8 @@ def my_info(request):
template = loader.get_template('members_space/my_info.html')
context = {
'title': 'Mes Infos',
'understand_my_status': getattr(settings, 'MEMBERS_SPACE_SHOW_UNDERSTAND_MY_STATUS', True)
'understand_my_status': getattr(settings, 'MEMBERS_SPACE_SHOW_UNDERSTAND_MY_STATUS', True),
'understand_my_status_template': getattr(settings, 'MEMBERS_SPACE_UNDERSTAND_MY_STATUS_TEMPLATE', "members_space/understand_my_status.html")
}
return HttpResponse(template.render(context, request))
......@@ -203,6 +219,7 @@ def shifts_exchange(request):
template = loader.get_template('members_space/shifts_exchange.html')
context = {
'title': 'Échange de Services',
'canAddShift': getattr(settings, 'CAN_ADD_SHIFT', False)
}
return HttpResponse(template.render(context, request))
......
......@@ -138,7 +138,7 @@ function debounceFunction(func, delay = 1000) {
*/
function handle_unauthorize() {
alert("La session a expiré. Vous allez devoir vous reconnecter.");
$( "#logout" ).trigger( "click" );
$("#logout").trigger("click");
}
/* - PRODUCTS */
......@@ -310,10 +310,11 @@ function compute_and_affect_product_supplier_quantities(coeff, days) {
const daily_conso = product.daily_conso;
let purchase_package_qty_for_coverage = compute_purchase_qty_for_coverage(product, coeff, stock, incoming_qty, daily_conso, days);
// Set qty to purchase for supplier with higher priority
let target_supplierinfo_index = 0;
let min_sequence = Number.POSITIVE_INFINITY; // min sequence = higher priority
let min_sequence = Number.POSITIVE_INFINITY; // min sequence = higher priority
for (let i in products[key].suppliersinfo) {
let suppliersinfo_sequence = products[key].suppliersinfo[i].sequence;
......@@ -491,7 +492,7 @@ function check_products_data() {
}
report_JS_error(err, 'orders');
alert(`Erreur lors de la vérification des données des articles. Certaines données peuvent être erronées`);
$('.notifyjs-wrapper').trigger('notify-hide');
// Don't block process if this call fails
resolve();
......@@ -559,15 +560,15 @@ function update_product_ref(input_el, p_id, p_index) {
handle_unauthorize();
} else {
let msg = "erreur serveur lors de la sauvegarde de la référence";
msg += ` (product_tmpl_id: ${product.id}`;
err = {msg: msg, ctx: 'update_product_ref'};
if (typeof data.responseJSON != 'undefined' && typeof data.responseJSON.error != 'undefined') {
err.msg += ' : ' + data.responseJSON.error;
}
report_JS_error(err, 'orders');
alert('Erreur lors de la sauvegarde de la référence dans Odoo. Veuillez recharger la page et ré-essayer plus tard.');
}
}
......@@ -637,7 +638,7 @@ function add_supplier() {
err.msg += ' : ' + data.responseJSON.error;
}
report_JS_error(err, 'orders');
closeModal();
alert('Erreur lors de la récupération des produits, réessayer plus tard.');
}
......@@ -741,15 +742,15 @@ function save_supplier_product_association(product, supplier, cell) {
handle_unauthorize();
} else {
let msg = "erreur serveur lors de la sauvegarde de l'association product/supplier";
msg += ` (product_tmpl_id: ${product.id}; supplier_id: ${supplier.id})`;
err = {msg: msg, ctx: 'save_supplier_product_association'};
if (typeof data.responseJSON != 'undefined' && typeof data.responseJSON.error != 'undefined') {
err.msg += ' : ' + data.responseJSON.error;
}
report_JS_error(err, 'orders');
closeModal();
alert('Erreur lors de la sauvegarde de l\'association. Veuillez ré-essayer plus tard.');
}
......@@ -800,13 +801,13 @@ function end_supplier_product_association(product, supplier) {
} else {
let msg = "erreur serveur lors de la suppression de l'association product/supplier".
msg += ` (product_tmpl_id: ${product.id}; supplier_id: ${supplier.id})`;
err = {msg: msg, ctx: 'end_supplier_product_association'};
if (typeof data.responseJSON != 'undefined' && typeof data.responseJSON.error != 'undefined') {
err.msg += ' : ' + data.responseJSON.error;
}
report_JS_error(err, 'orders');
closeModal();
alert('Erreur lors de la suppression de l\'association. Veuillez ré-essayer plus tard.');
}
......@@ -980,13 +981,13 @@ function commit_actions_on_product(product, inputs) {
} else {
let msg = "erreur serveur lors de la sauvegarde".
msg += ` (product_tmpl_id: ${product.id})`;
err = {msg: msg, ctx: 'commit_actions_on_product'};
if (typeof data.responseJSON != 'undefined' && typeof data.responseJSON.error != 'undefined') {
err.msg += ' : ' + data.responseJSON.error;
}
report_JS_error(err, 'orders');
try {
if (data.responseJSON.code === "archiving_with_incoming_qty") {
alert("Ce produit a des quantités entrantes, vous ne pouvez pas l'archiver.");
......@@ -998,7 +999,7 @@ function commit_actions_on_product(product, inputs) {
} catch (error) {
alert('Erreur lors de la sauvegarde des données. Veuillez ré-essayer plus tard.');
}
check_products_data()
.then(() => {
update_cdb_order();
......@@ -1079,14 +1080,14 @@ function generate_inventory() {
} else {
$('#do_inventory').empty()
.append(`Faire un inventaire`);
let msg = "erreur serveur lors de la création de l'inventaire".
let msg = "erreur serveur lors de la création de l'inventaire",
err = {msg: msg, ctx: 'generate_inventory'};
if (typeof data.responseJSON != 'undefined' && typeof data.responseJSON.error != 'undefined') {
err.msg += ' : ' + data.responseJSON.error;
}
report_JS_error(err, 'orders');
alert("Erreur lors de la création de l'inventaire. Réessayez plus tard.");
}
}
......@@ -1362,13 +1363,13 @@ function create_orders() {
handle_unauthorize();
} else {
let msg = "erreur serveur lors de la création des product orders";
err = {msg: msg, ctx: 'save_supplier_product_association', data: orders_data};
if (typeof data.responseJSON != 'undefined' && typeof data.responseJSON.error != 'undefined') {
err.msg += ' : ' + data.responseJSON.error;
}
report_JS_error(err, 'orders');
closeModal();
alert('Erreur lors de la création des commandes. Veuillez ré-essayer plus tard.');
}
......@@ -2826,7 +2827,7 @@ $(document).ready(function() {
err.msg += ' : ' + data.responseJSON.error;
}
report_JS_error(err, 'orders');
closeModal();
alert('Erreur lors de la récupération des fournisseurs, rechargez la page plus tard');
}
......
......@@ -123,7 +123,7 @@ def get_orders_attachment(request):
for item in res:
if 'error' in item:
return JsonResponse(res, status=500)
return JsonResponse(res, status=500, safe=False)
return JsonResponse({'res': res})
......@@ -133,6 +133,7 @@ def export_one(request, oid):
oid = int(oid)
order = Order(oid)
order_data = order.export()
if ('success' in order_data) and (order_data['success'] is True):
now = datetime.datetime.now()
taxes = 0
......@@ -176,7 +177,7 @@ def export_one(request, oid):
# return response
except Exception as e:
msg = str(e)
coop_logger.error("Order export error : %s", msg)
return JsonResponse({"msg": msg}, safe=False)
def export_regex(request, string):
......@@ -258,4 +259,4 @@ def print_product_labels(request):
res['errors'].append(pres)
except Exception as e:
res['error_ext'] = str(e)
return JsonResponse({'res': res}, safe=False)
\ No newline at end of file
return JsonResponse({'res': res}, safe=False)
......@@ -131,6 +131,10 @@
La Cagette use False to implement custom rules
- CAN_CREATE_BINOME = True (by default)
If set to True, in new member creation form, a member can be selected to be associated with.
- ASSOCIATE_MEMBER_SHIFT = ''
Id number of the associate shift template
......@@ -326,6 +330,11 @@
- MEMBERS_SPACE_FAQ_TEMPLATE = None
If set to None, "FAQ menu" will not be shown. To use a custom content add a template and set it's relative path
- MEMBERS_SPACE_HOME_TEMPLATE = 'members_space/supercafoutch/home.html'
If not set, 'members_space/home.html' (la Cagette)
- MEMBERS_SPACE_SHOW_UNDERSTAND_MY_STATUS = False
By default, is True. If False, tile showing explanations is not shown
......@@ -333,6 +342,10 @@
- BLOCK_ACTIONS_FOR_ATTACHED_PEOPLE = False
Attached people can or not change his services
- CAN_ADD_SHIFT = True
By default, False. Set if coop can or not add shifts in their memberspace calendar
### Reception
- RECEPTION_ADD_ADMIN_MODE = True
......@@ -410,8 +423,31 @@
- START_DATE_FOR_SHIFTS_HISTORY = "2018-01-01"
- AMNISTIE_DATE = "2021-11-24 00:00:00"
In members_space history display a special activity about amnistie
- MEMBERS_SPACE_FAQ_TEMPLATE = 'members_space/supercoop/faq.html'
Set alternative template for FAQ
- MEMBERS_SPACE_HOME_TEMPLATE = 'members_space/supercoop/home.html'
Set alternative template for home page
- MEMBERS_SPACE_UNDERSTAND_MY_STATUS_TEMPLATE = 'members_space/supercoop/understand_my_status.html'
Set alternative template for understand my status
- SHOW_ABCD_CALENDAR_TAB = False
True by default
- PERMANENT_MESSAGE_BELOW_CONNECTION_FIELDS = "Si vous avez des difficultés à vous connecter, ...."
Default is None
- STANDARD_BLOCK_SERVICE_EXCHANGE_DELAY = 36 (default = 24)
Define duration, in hours, before shift starts within exchange is not more available, for standard shift_type member
### BDM Admin
......@@ -419,6 +455,10 @@
If True, in BDM Admin manage shift template, on the calendar when subscribing a partner to a shift, "Volant" button is included
- ADMIN_BINOME_ACTIVE = False
By defaut, True. Show "Gestion des binômes" in bdm admin
### Miscellious
- EXPORT_COMPTA_FORMAT = 'Quadratus'
......
......@@ -23,5 +23,6 @@ def context_setting(request):
"""adding settings variable to context (can be overloaded in views)."""
context = {'odoo': settings.ODOO['url'],
'app_env': getattr(settings, 'APP_ENV', "prod"),
'company_code': getattr(settings, 'COMPANY_CODE', '')}
'company_code': getattr(settings, 'COMPANY_CODE', ''),
'favicon_url': getattr(settings, 'FAVICON_URL', '/static/favicon.ico')}
return context
\ No newline at end of file
......@@ -23,7 +23,7 @@ var volant = null;
function get_displayed_weeks() {
displayed_weeks = [];
week_types.find('.selected_weeks :checked').each(function() {
$('#week_types').find('.selected_weeks :checked').each(function() {
displayed_weeks.push($(this).val());
});
......@@ -32,7 +32,7 @@ function get_displayed_weeks() {
function get_shift_name(s_data) {
var shift_name = "Inconnu";
if (typeof ASSOCIATE_MEMBER_SHIFT == "undefined") ASSOCIATE_MEMBER_SHIFT = "";
if (s_data && s_data.week) {
shift_name = weeks_name[s_data.week];
if (s_data.type == 2 && typeof manage_ftop != "undefined" && manage_ftop == true && s_data.id != ASSOCIATE_MEMBER_SHIFT) {
......@@ -112,7 +112,7 @@ function select_shift_among_compact(event, clicked_item = null, subscribe = true
var worst_score = 1;
displayed_weeks = get_displayed_weeks();
var place_cond = sc_lat.find('.highlighted').data('select');
var place_cond = sc_lat.find('.highlighted').data('select') || "";
$.each(shift_templates, function(i, e) {
if (e.data) {
......@@ -135,14 +135,23 @@ function select_shift_among_compact(event, clicked_item = null, subscribe = true
}
});
if (selected && subscribe === true)
subscribe_shift(selected);
if (selected && subscribe === true){
if (typeof partner_data !== "undefined" && typeof partner_data.barcode_base !== "undefined") {
//click is coming from memberspace
process_asked_shift_template_change(selected);
} else {
subscribe_shift(selected);
}
}
return selected
}
function draw_table(begin_hours, callback) {
if (shift_table.length == 0) shift_table = $('#shift_choice table');
shift_table.find('tbody tr').remove();
begin_hours.sort();
var days = [
......@@ -172,14 +181,15 @@ function draw_table(begin_hours, callback) {
}
function draw_shift_templates() {
function draw_shift_templates(external) {
if (typeof external !== "undefined" && external == true) shift_table = $('#shift_choice table');
var existing_shifts = shift_table.find('.shift');
existing_shifts.off("click", single_shift_click);
existing_shifts.off("click", select_shift_among_compact);
existing_shifts.remove();
var place_cond = sc_lat.find('.highlighted').data('select');
var place_cond = sc_lat.find('.highlighted').data('select') || "";
//warning MAG_NAME should correspond to data.place value of shift_templates objects
dispo = 0;
......@@ -199,7 +209,7 @@ function draw_shift_templates() {
if (e.data.begin <= max_begin_hour && e.data.max > 0 && (place_cond == 'both' || place_cond == place)) {
keep_it = true;
}
}
if (keep_it == true && displayed_weeks.indexOf(e.data.week.toString()) > -1) {
var known_begin_hour = false;
......@@ -272,7 +282,6 @@ function draw_shift_templates() {
boxes[e.data.day+'_'+e.data.begin]['profil'] = profile;
}
}
}
}
......@@ -280,6 +289,7 @@ function draw_shift_templates() {
}
});
if (type == 1) {
shift_table.find('.shift').on("click", single_shift_click);
}
......@@ -311,16 +321,19 @@ function draw_shift_templates() {
sc_lat.find('.info').html(dispo + ' places disponibles<br />(/'+max+')');
closeModal();
if (typeof external == "undefined") {
closeModal();
}
});
}
function retrieve_and_draw_shift_tempates() {
openModal();
function retrieve_and_draw_shift_tempates(external) {
if (shift_table.length == 0) shift_table = $('#shift_choice table');
if (!external) {
openModal();
}
shift_table.find('.shift').remove();
......@@ -333,7 +346,7 @@ function retrieve_and_draw_shift_tempates() {
if (e.data.type == 2 && volant == null) {
// has comitee shift
if (committees_shift_id !== undefined && committees_shift_id !== "None") {
if (typeof committees_shift_id !== "undefined" && committees_shift_id !== "None") {
if (e.data.id == parseInt(committees_shift_id)) {
volant = e.data.id
}
......@@ -342,33 +355,39 @@ function retrieve_and_draw_shift_tempates() {
}
}
});
dbc.allDocs({include_docs: true, descending: true}, function(err, resp) {
if (err) {
return console.log(err);
}
$.each(resp.rows, function(i, e) {
if (e.doc.shift_template && typeof(e.doc.shift_template.data) != "undefined") {
try {
if (typeof shift_templates[e.doc.shift_template.data.id]!= "undefined")
shift_templates[e.doc.shift_template.data.id]['data']['reserved'] += 1;
} catch (ec) {
console.log(ec);
}
if (typeof dbc !== "undefined") {
dbc.allDocs({include_docs: true, descending: true}, function(err, resp) {
if (err) {
return console.log(err);
}
$.each(resp.rows, function(i, e) {
if (e.doc.shift_template && typeof(e.doc.shift_template.data) != "undefined") {
try {
if (typeof e.doc.odoo_id == "undefined" || isNaN(e.doc.odoo_id)) {
if (typeof shift_templates[e.doc.shift_template.data.id] != "undefined")
shift_templates[e.doc.shift_template.data.id]['data']['reserved'] += 1;
}
} catch (ec) {
console.log(ec);
}
}
});
draw_shift_templates(external);
});
draw_shift_templates();
});
} else {
draw_shift_templates(external);
}
});
}
function filter_weeks() {
function filter_weeks(external) {
var clicked = $(this);
var week_types = $('#week_types');
var parent_div = clicked.closest('div');
var w1 = week_types.find('#dw1');
var w2 = week_types.find('#dw2');
......@@ -411,8 +430,7 @@ function filter_weeks() {
if (!w2.is(':checked') || !w4.is(':checked')) {
$('#odd_weeks').prop('checked', false);
}
draw_shift_templates();
draw_shift_templates(external);
}
function shift_loc_selection() {
......
......@@ -88,7 +88,7 @@ class FieldsView(View):
u"""Nous allons retourner les attributs Odoo correspondants."""
entity = request.POST.get("entity", "")
fields = []
if len(entity) > 1:
if getattr(settings, 'APP_ENV', "prod") == "dev" and len(entity) > 1:
api = OdooAPI()
fields = api.get_entity_fields(entity)
template = loader.get_template('common/entity_fields.html')
......
......@@ -1979,10 +1979,12 @@ function add_products_action() {
for (let qty_input of qty_inputs) {
if ($(qty_input).val() === "") {
has_empty_qty_input = true;
$(qty_input).closest(".product_qty").find(".product_qty_input_alert")
$(qty_input).closest(".product_qty")
.find(".product_qty_input_alert")
.show();
} else {
$(qty_input).closest(".product_qty").find(".product_qty_input_alert")
$(qty_input).closest(".product_qty")
.find(".product_qty_input_alert")
.hide();
}
}
......@@ -2024,8 +2026,10 @@ function create_orders() {
for (let i = 0; i < add_products_lines.length; i++) {
let line = add_products_lines[i];
if ($(line).find(".product_name").text() === p.name) {
product_uom = $(line).find(".product_uom").text();
if ($(line).find(".product_name")
.text() === p.name) {
product_uom = $(line).find(".product_uom")
.text();
if (product_uom.includes("kg")) {
product_qty = parseFloat($(line).find(".product_qty_input")
......@@ -2045,15 +2049,16 @@ function create_orders() {
// If package qty is > than input value, package qty will be used while creating order
let package_qty = p_supplierinfo.package_qty;
if (product_qty < package_qty) {
package_qty = product_qty;
}
// Round differently for unit & kg products
if (product_uom.includes("kg") ) {
if (product_uom.includes("kg")) {
item_qty_package = Math.round((product_qty / package_qty) * 1e2) / 1e2;
} else {
item_qty_package = Math.round(product_qty / package_qty)
item_qty_package = Math.round(product_qty / package_qty);
}
orders_data.suppliers_data[supplier_id].lines.push({
......
......@@ -591,4 +591,4 @@ class Shelfs(models.Model):
except Exception as e:
res['error'] = str(e)
coop_logger.error("Rayons, make_products_shelf_links : %s", str(e))
return res
\ No newline at end of file
return res
......@@ -215,6 +215,11 @@ def change_shift(request):
response = {'msg': "Old service in less than 24hours."}
return JsonResponse(response, status=400)
if cs.is_shift_exchange_allowed(idOldShift, data["idShift"], data["shift_type"], data["idPartner"]) is False:
response = {'msg': "Not allowed to change shift"}
return JsonResponse(response, status=400)
st_r_id = False
#Insertion du nouveau shift
try:
......@@ -281,8 +286,11 @@ def add_shift(request):
"idPartner": int(request.POST['idPartner']),
"idShift":int(request.POST['idNewShift']),
"shift_type":request.POST['shift_type'],
"is_makeup":True
"is_makeup": False
}
if 'is_makeup' in request.POST and request.POST['is_makeup'] == "1":
data['is_makeup'] = True
#Insertion du nouveau shift
st_r_id = False
......
......@@ -365,7 +365,17 @@ class CagetteStock(models.Model):
return res
@staticmethod
def get_valuable_stock():
articles = []
try:
api = OdooAPI()
cond = [['qty_available','>', 0], ['active', '=', True]]
fields = ["barcode", "display_name", "qty_available", "standard_price"]
articles = api.search_read('product.product', cond, fields, 1000000)
except Exception as e:
coop_logger.error("Erreur get_valuable_stock : %s", str(e))
return articles
def set_test():
o_api = OdooAPI()
......
$(document).ready(function() {
table_article = $('#tableArticle').DataTable({
"ajax": {
"url": "get_valuable_stock",
"data": ""
},
"columns":[
{data:"barcode", "title":"Code-barre", "width": "50%"},
{data:"display_name", "title":"Article", "width": "50%"},
{data:"qty_available", "title":"Stock", "width":"15%"
},
{data:"standard_price", "title":"Prix achat", "width":"15%"
}
],
"searching": true,
"order": [
[
2,
"desc"
]
],
"iDisplayLength": 50,
"language": {
"emptyTable": "Pas de donnée",
"info": "Affiché : lignes _START_ à _END_ sur _TOTAL_",
"infoEmpty": "Affiché : 0 ligne",
"infoFiltered": "(filtré de _MAX_ lignes au total)",
"thousands": ",",
"lengthMenu": "Afficher _MENU_ lignes",
"loadingRecords": "Loading...",
"processing": "Processing...",
"search": "Rechercher un article :",
"searchPlaceholder": "Référence, code-barre",
"zeroRecords": "Aucun résultat",
"paginate": {
"first": "Premier",
"last": "Dernier",
"next": "Suivant",
"previous": "Precedant"
},
"aria": {
"sortAscending": ": activate to sort column ascending",
"sortDescending": ": activate to sort column descending"
}
},
buttons: [
{
extend: 'excelHtml5',
text: 'Export en Excel',
className: 'btn--primary btn_export'
},
],
dom: '<lr<t>ip><"clear"><B>',
});
});
\ No newline at end of file
......@@ -46,4 +46,8 @@ urlpatterns = [
url(r'^get_saleWitheNotSale', views.get_saleWitheNotSale),
url(r'^get_test', views.get_test),
# Values
url(r'^stockValues', views.stockValues),
url(r'^get_valuable_stock', views.get_valuable_stock),
]
......@@ -550,8 +550,16 @@ def get_saleWitheNotSale(request):
return JsonResponse({"data":lArticleSale}, safe=True)
def stockValues(request):
"""Page valeurs du stock (quantités positives)."""
context = {'title': 'Stock (quantités positives valorisées)'}
template = loader.get_template('stock/stock_values.html')
return HttpResponse(template.render(context, request))
def get_valuable_stock(request):
articles = CagetteStock.get_valuable_stock()
return JsonResponse({"data":articles}, safe=True)
def get_test(request):
res = CagetteStock.get_sale_qty_by_from(1)
return JsonResponse({"data":res}, safe=False)
......@@ -14,7 +14,7 @@
{% endfor %}
{% endif %}
<link rel="shortcut icon" type="image/png" href="{% static "favicon.ico" %}"/>
<link rel="shortcut icon" type="image/png" href="{{favicon_url}}"/>
{% block additionnal_css %}{% endblock %}
<script type="text/javascript">
// Prevent back page
......
......@@ -29,10 +29,12 @@
Gestion des présences
<span class="management_type_button_icons"><i class="fas fa-arrow-right"></i></span>
</button><br>
{% if admin_binome_active %}
<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-arrow-right"></i></span>
</button><br>
{% endif %}
<button type="button" class="btn--primary management_type_button" id="manage_regular_shifts_button">
Gestion des créneaux
<span class="management_type_button_icons"><i class="fas fa-arrow-right"></i></span>
......
......@@ -79,7 +79,7 @@
</div>
</div>
<div id="modal_error_change_shift_template">
<h3 class="error_modal_title""">Action impossible</h3>
<h3 class="error_modal_title">Action impossible</h3>
<p>
Le ou la membre est inscrit.e à un rattrapage sur le créneau choisi (<span class="shift_template_name"></span>), cela empêche de l'inscrire sur ce créneau.
</p>
......
......@@ -141,7 +141,9 @@
<div class="col-2 row-2">
<a class="btn btn--primary" data-next="first_page" >Retour accueil</a>
</div>
<div class="col-2 row-2"></div>
<div class="col-2 row-2 txtcenter">
<div id="current_shift_process_data_actions" style="display:none;"></div>
</div>
<div class="col-2 row-2 login_area">
{% include "common/conn_admin.html" %}
</div>
......
......@@ -79,16 +79,18 @@
</p>
{% endif %}
{% if ASSOCIATE_MEMBER_SHIFT %}
{% if can_create_binome %}
<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>
{% if ASSOCIATE_MEMBER_SHIFT %}
<div id="new_member_choice" class="member_choice">
A mettre en binome avec un.e nouveau membre
</div>
{% endif %}
</div>
<div id="existing_member_choice_action" style="display:none;">
......@@ -110,6 +112,7 @@
</div>
</div>
</div>
{% if ASSOCIATE_MEMBER_SHIFT %}
<div id="new_member_choice_action" style="display:none;">
<div >
<div>
......@@ -117,6 +120,7 @@
</div>
</div>
</div>
{% endif %}
</div>
{% endif %}
<div>
......
<table class="table">
<caption>Calendrier fixe</caption>
<thead>
<tr>
<th scope="col" class="firstcol"></th>
<th scope="col">Lundi</th>
<th scope="col">Mardi</th>
<th scope="col">Mercredi</th>
<th scope="col">Jeudi</th>
<th scope="col">Vendredi</th>
<th scope="col">Samedi</th>
{% if open_on_sunday %}
<th scope="col">Dimanche</th>
{% endif %}
</tr>
</thead>
<tbody>
</tbody>
</table>
<div id="week_types" class="clearfix">
<div class="oddeven_selector fl">
<input type="checkbox" class="switch" id="even_weeks" value='0' checked><label for="even_weeks">Paires</label>
<input type="checkbox" class="switch" id="odd_weeks" value='1' checked><label for="odd_weeks">Impaires</label>
</div>
<div class="selected_weeks fl">
<input type="checkbox" class="switch" id="dw1" value='1' checked><label for="c1">A</label>
<input type="checkbox" class="switch" id="dw2" value='2' checked><label for="c2">B</label>
<input type="checkbox" class="switch" id="dw3" value='3' checked><label for="c3">C</label>
<input type="checkbox" class="switch" id="dw4" value='4' checked><label for="c4">D</label>
</div>
</div>
{% if type and type == 1 %}
<!--<div class="clearfix mtop25">Le trait <span class="alert">rouge</span> signale que le créneau est rempli à moins de 75%</div>-->
{% endif %}
\ No newline at end of file
......@@ -12,41 +12,7 @@
<div class="info"></div>
</div>
<div class="col-5 main_content">
<table class="table">
<caption>Calendrier fixe</caption>
<thead>
<tr>
<th scope="col" class="firstcol"></th>
<th scope="col">Lundi</th>
<th scope="col">Mardi</th>
<th scope="col">Mercredi</th>
<th scope="col">Jeudi</th>
<th scope="col">Vendredi</th>
<th scope="col">Samedi</th>
{% if open_on_sunday %}
<th scope="col">Dimanche</th>
{% endif %}
</tr>
</thead>
<tbody>
</tbody>
</table>
<div id="week_types" class="clearfix">
<div class="oddeven_selector fl">
<input type="checkbox" class="switch" id="even_weeks" value='0' checked><label for="even_weeks">Paires</label>
<input type="checkbox" class="switch" id="odd_weeks" value='1' checked><label for="odd_weeks">Impaires</label>
</div>
<div class="selected_weeks fl">
<input type="checkbox" class="switch" id="dw1" value='1' checked><label for="c1">A</label>
<input type="checkbox" class="switch" id="dw2" value='2' checked><label for="c2">B</label>
<input type="checkbox" class="switch" id="dw3" value='3' checked><label for="c3">C</label>
<input type="checkbox" class="switch" id="dw4" value='4' checked><label for="c4">D</label>
</div>
</div>
{% if type and type == 1 %}
<!--<div class="clearfix mtop25">Le trait <span class="alert">rouge</span> signale que le créneau est rempli à moins de 75%</div>-->
{% endif %}
{% include "members/shift_template_calendar.html" %}
</div>
</section>
\ No newline at end of file
......@@ -13,6 +13,7 @@
{% if show_faq %}
<a href="javascript:void(0);" class="nav_item" id="nav_faq">Problèmes et Demandes</a>
{% endif %}
{% if show_abcd_calendar %}
<a
href="javascript:void(0);"
target="_blank"
......@@ -21,7 +22,7 @@
>
Calendrier ABCD
</a>
{% endif %}
{# Disconnection button must have this id (logic in all_common.js) #}
<a href="javascript:void(0);" id="deconnect">Déconnexion</a>
<a href="javascript:void(0);" class="icon" onclick="toggleHeader()">
......
......@@ -28,6 +28,9 @@
<div class="member_shift_name_area">
<span>Mon créneau : </span>
<span class="member_shift_name member_info"></span>
{% if coop_can_change_shift_template %}
<span><i class="fas fa-edit tile_icon edit-btn"></i></span>
{% endif %}
</div>
<div class="member_coop_number_area">
<span>Mon numéro de coop : </span>
......@@ -118,4 +121,15 @@
</div>
</div>
</div>
{% if coop_can_change_shift_template %}
<div id="modal-calendar-choice" style="display:none;">
<div id="shift_choice">
{% include "members/shift_template_calendar.html" %}
</div>
</div>
<script>
var max_begin_hour = "{{max_begin_hour}}",
type = 2;
</script>
{% endif %}
</div>
......@@ -17,6 +17,7 @@
<script type="text/javascript" src="{% static 'js/datatables/dataTables.responsive.min.js' %}"></script>
<script type="text/javascript" src="{% static 'fullcalendar-5.9.0/lib/main.min.js' %}"></script>
<script type="text/javascript" src="{% static 'fullcalendar-5.9.0/lib/locales/fr.js' %}"></script>
<script type="text/javascript" src="{% static 'js/notify.min.js' %}?v=1651853225"></script>
{% endblock %}
{% block content %}
......@@ -126,7 +127,7 @@
var days_to_hide = "{{daysToHide}}"
var partner_data = {
"partner_id":"{{partnerData.id}}",
"name":"{{partnerData.display_name}}",
"name":"{{partnerData.display_name|safe}}",
"shift_type":"{{partnerData.shift_type}}",
"date_delay_stop":"{{partnerData.date_delay_stop}}",
"cooperative_state":"{{partnerData.cooperative_state}}",
......@@ -134,27 +135,29 @@
"can_have_delay" : "{{partnerData.can_have_delay}}",
"makeups_to_do" : "{{partnerData.makeups_to_do}}",
"barcode_base" : "{{partnerData.barcode_base}}",
"street" : "{{partnerData.street}}",
"street2" : "{{partnerData.street2}}",
"street" : "{{partnerData.street|safe}}",
"street2" : "{{partnerData.street2|safe}}",
"zip" : "{{partnerData.zip}}",
"city" : "{{partnerData.city}}",
"city" : "{{partnerData.city|safe}}",
"mobile" : "{{partnerData.mobile}}",
"phone" : "{{partnerData.phone}}",
"email" : "{{partnerData.email}}",
"is_associated_people" : "{{partnerData.is_associated_people}}",
"parent_id" : "{{partnerData.parent_id}}",
"parent_name" : "{{partnerData.parent_name}}",
"parent_name" : "{{partnerData.parent_name|safe}}",
"parent_verif_token" : "{{partnerData.parent_verif_token}}",
"associated_partner_id" : "{{partnerData.associated_partner_id}}",
"associated_partner_name" : "{{partnerData.associated_partner_name}}",
"associated_partner_name" : "{{partnerData.associated_partner_name|safe}}",
"verif_token" : "{{partnerData.verif_token}}",
"leave_stop_date": "{{partnerData.leave_stop_date}}",
"comite": "{{partnerData.comite}}",
"extra_shift_done": parseInt("{{partnerData.extra_shift_done}}", 10)
};
var block_actions_for_attached_people = '{{block_actions_for_attached_people}}';
const canAddShift = {{canAddShift}};
</script>
<script src="{% static "js/all_common.js" %}?v=1651853225"></script>
<script src="{% static "js/common.js" %}?v=1651853225"></script>
<script src="{% static "js/members-space-home.js" %}?v=1651853225"></script>
<script src="{% static "js/members-space-my-info.js" %}?v=1651853225"></script>
<script src="{% static "js/members-space-my-shifts.js" %}?v=1651853225"></script>
......
......@@ -106,7 +106,7 @@
</div>
</div>
{% if understand_my_status %}
{% include "members_space/understand_my_status.html" %}
{% include ""|add:understand_my_status_template %}
{% endif %}
</div>
</div>
......@@ -50,6 +50,9 @@
<i class="fas fa-spinner fa-spin fa-lg"></i>
</div>
<div id="shifts_list"></div>
{% if canAddShift %}
<button class="btn--primary selectable_shift_line" id="start_adding_shift"><strong>+ Ajouter un service</strong></button>
{% endif %}
</div>
<div id="calendar_explaination_area"></div>
<button id="calendar_explaination_button" class="btn--success">Légende du calendrier</button>
......
<div id="home">
<div class="page_title txtcenter">
<h1>Espace Membre</h1>
</div>
<div class="tiles_container">
<div class="tile high_tile" id="home_tile_my_info">
<div class="tile_title">
<i class="fas fa-user tile_icon"></i>
<span class="member_info member_name"></span>
</div>
<div class="tile_content">
{# <p><span class="member_info member_name"></span></p> #}
<p class="member_status_text_container">Mon statut : <span class="member_info member_status"></span></p>
<div class="delay_date_stop_container">
( jusqu'au <span class="delay_date_stop"></span> )
</div>
<div id="member_status_action">
<a href="#" target="_blank" class="btn--warning unsuscribed_form_link">
J'accède au formulaire
</a>
<button type="button" class="btn--danger choose_makeups">
Je sélectionne mes rattrapages
</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 class="member_shift_name_area">
<span>Mon créneau : </span>
<span class="member_shift_name member_info"></span>
</div>
<div class="member_coop_number_area">
<span>Mon numéro de coop : </span>
<span class="member_coop_number member_info"></span>
</div>
<div class="member_associated_partner_area">
<span>Je suis en binôme avec : </span>
<span class="member_associated_partner member_info"></span>
</div>
<div id="see_more_info">
<button type="button", class="btn btn--primary home_link_button" id="see_more_info_link">
Accéder à mes infos et comprendre mon statut
</button>
</div>
</div>
</div>
<div class="tile high_tile" id="home_tile_my_services">
<div class="tile_title">
<i class="fas fa-clipboard tile_icon"></i>
Mes Services
</div>
<div class="tile_content">
<h3>Services à venir</h3>
<div id="home_incoming_services">
<i class="fas fa-spinner fa-spin fa-lg"></i>
</div>
<div id="go_to_shift_history_area">
<button type="button", class="btn btn--primary" id="home_go_to_shift_history">
Accéder à mon historique
</button>
</div>
</div>
</div>
<div class="tile small_tile" id="home_tile_services_exchange">
<div class="tile_title">
<i class="fas fa-exchange-alt tile_icon"></i>
Échange de services
</div>
<div class="tile_content">
<div>
Un empêchement ? J'anticipe et déplace mes services jusqu'à 24h avant leur début !
</div>
<div class="home_link_button_area">
<button type="button" class="btn--primary home_link_button" id="go_to_shifts_calendar">
Accéder au calendrier d'échange de services
</button>
</div>
</div>
</div>
<div class="tile small_tile" id="home_tile_help">
<div class="tile_title">
<i class="fas fa-question-circle tile_icon"></i>
J'ai une demande
</div>
<div class="tile_content">
<div class="home_link_button_area">
<a
href="javascript:void(0);"
class="btn--primary home_link_button"
id="go_to_forms"
>
Accéder à la FAQ
</a>
</div>
</div>
</div>
<div class="tile small_tile" id="home_tile_shop_info">
<div class="tile_title">
<i class="fas fa-newspaper tile_icon"></i>
Informations magasins
</div>
<div id="shop_info_content">
<div class="shop_info_item shop_opening_hours">
<div class="shop_info_item_content">
<div class="opening_hours_title">
Horaires du magasin :
</div>
<div class="opening_hours_content">
{{shop_opening_hours|safe}}
</div>
</div>
</div>
<div class="shop_info_item shop_message">
<div class="shop_info_item_content shop_message_content">
{{msg_accueil|safe}}
</div>
</div>
</div>
</div>
</div>
</div>
<div id="faqBDM" class=" mt-3">
<div class="page_title txtcenter"><h1> Problèmes et demandes </h1></div>
<div class="tiles_container">
<div class="tile full_width_tile">
<p>
<a href="https://supercoop.notion.site/supercoop/Foire-Aux-Questions-sur-la-participation-et-Formulaires-correspondants-106143413d0b400a9f94023962375304" target="_blank">Foire-Aux-Questions-sur-la-participation-et-Formulaires</a>
</p>
<p>
<em>En cliquant sur le lien ci-dessus, un nouvel onglet ou une nouvelle fenêtre affichera le contenu de la page sur le site supercoop.notion.site.</em>
</p>
</div>
</div>
</div>
<div id="home">
<div class="page_title txtcenter">
<h1>Bienvenue sur ton nouvel espace membre ! 🎉</h1>
<strong>Si tu es ex-volant.e</strong>, il te faut absolument changer ton créneau volant (DDim 22:00)par un créneau régulier qui te convient ou le moins pire... (ci-dessous)<br/> Ensuite, tu peux déplacer ton prochain service programmé en allant sur "Echanges de services" 🤙<br/>
Si tu es régulier.e, rien ne change pour toi si ce n'est que tu peux anticiper une absence en déplaçant ton service. Tu n'as plus à rechercher de remplaçant ✌️<br/>
Concernant les <strong>binômes</strong>, il nous faut un peu plus de temps pour déployer cette nouveauté. On te tiens au courant via le mail hebdo 😉<br/>
Si jamais ça ne marche pas, contactes-nous à support@supercoop.fr 📧<br/>
</div>
<div>
</div>
<div class="tiles_container">
<div class="tile high_tile" id="home_tile_my_info">
<div class="tile_title">
<i class="fas fa-user tile_icon"></i>
<span class="member_info member_name"></span>
</div>
<div class="tile_content">
{# <p><span class="member_info member_name"></span></p> #}
<p class="member_status_text_container">Mon statut : <span class="member_info member_status"></span></p>
<div class="delay_date_stop_container">
( jusqu'au <span class="delay_date_stop"></span> )
</div>
<div id="member_status_action">
<a href="#" target="_blank" class="btn--warning unsuscribed_form_link">
J'accède au formulaire
</a>
<button type="button" class="btn--danger choose_makeups">
Je sélectionne mes rattrapages
</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 class="member_shift_name_area">
<span>Mon créneau : </span>
<span class="member_shift_name member_info"></span>
{% if coop_can_change_shift_template %}
<span><i class="fas fa-edit tile_icon edit-btn"></i></span>
{% endif %}
</div>
<div class="member_coop_number_area">
<span>Mon numéro de coop : </span>
<span class="member_coop_number member_info"></span>
</div>
<div class="member_associated_partner_area">
<span>Je suis en binôme avec : </span>
<span class="member_associated_partner member_info"></span>
</div>
<div id="see_more_info">
<button type="button", class="btn btn--primary home_link_button" id="see_more_info_link">
Accéder à mes infos et comprendre mon statut
</button>
</div>
</div>
</div>
<div class="tile high_tile" id="home_tile_my_services">
<div class="tile_title">
<i class="fas fa-clipboard tile_icon"></i>
Mes Services
</div>
<div class="tile_content">
<h3>Services à venir</h3>
<div id="home_incoming_services">
<i class="fas fa-spinner fa-spin fa-lg"></i>
</div>
<div id="go_to_shift_history_area">
<button type="button", class="btn btn--primary" id="home_go_to_shift_history">
Accéder à mon historique
</button>
</div>
</div>
</div>
<div class="tile small_tile" id="home_tile_services_exchange">
<div class="tile_title">
<i class="fas fa-exchange-alt tile_icon"></i>
Échange de services
</div>
<div class="tile_content">
<div>
Un empêchement ? J'anticipe et déplace mes services jusqu'à 24h avant leur début !
</div>
<div class="home_link_button_area">
<button type="button" class="btn--primary home_link_button" id="go_to_shifts_calendar">
Accéder au calendrier d'échange de services
</button>
</div>
</div>
</div>
<div class="tile small_tile" id="home_tile_help">
<div class="tile_title">
<i class="fas fa-question-circle tile_icon"></i>
J'ai une demande
</div>
<div class="tile_content">
<div class="home_link_button_area">
<a
href="javascript:void(0);"
class="btn--primary home_link_button"
id="go_to_forms"
>
Accéder aux formulaires
</a>
</div>
</div>
</div>
<div class="tile small_tile" id="home_tile_shop_info">
<div class="tile_title">
<i class="fas fa-newspaper tile_icon"></i>
Informations magasins
</div>
<div id="shop_info_content">
<div class="shop_info_item shop_opening_hours">
<div class="shop_info_item_content">
<div class="opening_hours_title">
Horaires du magasin :
</div>
<div class="opening_hours_content">
{{shop_opening_hours|safe}}
</div>
</div>
</div>
<div class="shop_info_item shop_message">
<div class="shop_info_item_content shop_message_content">
{{msg_accueil|safe}}
</div>
</div>
</div>
</div>
</div>
{% if coop_can_change_shift_template %}
<div id="modal-calendar-choice" style="display:none;">
<div id="shift_choice">
{% include "members/shift_template_calendar.html" %}
</div>
</div>
<div id="modal_error_change_shift_template" style="display:none;">
<h3 class="error_modal_title">Action impossible</h3>
<p>
Il y a un rattrapage sur le créneau choisi (<span class="shift_template_name"></span>), cela empêche de s'inscrire sur ce créneau.
</p>
<p>Vous pouvez essayer ce créneau une autre semaine.</p>
</div>
<script>
var max_begin_hour = "{{max_begin_hour}}",
type = 2;
</script>
{% endif %}
</div>
<div class="tile full_width_tile">
<div class="tile_title">
Comprendre mon statut
</div>
<div class="my_info_line_middle">
Il existe différents statuts donnant ou non le droit de faire ses courses. Voici un schéma explicatif expliquant le passage d'un statut à un autre. Pour toute question relative aux statuts, rendez&#x2011;vous dans la rubrique <a href='faq'>Problèmes&nbsp;&&nbsp;Demandes</a>.
</div>
<a href="/static/img/Diagramme_Etat_Statut_Cooperateurs_Supercoop_220909.jpg" target=”_blank”>
<img class="status_info_image" src="/static/img/Diagramme_Etat_Statut_Cooperateurs_Supercoop_220909.jpg" alt="diagramme_etat_statut_cooperateurs"/>
</a>
</div>
\ No newline at end of file
......@@ -31,6 +31,7 @@
<a class="dropdown-item" href="breakingArticleSet">Mettre en rupture un article sur odoo</a>
<a class="dropdown-item" href="stockQuantLastSale">Date de la dernière vente des articles</a>
<a class="dropdown-item" href="saleWithNotSale">Vente avec jours sans vente</a>
<a class="dropdown-item" href="stockValues">Stock (qtés > 0 valorisées)</a>
</div>
</li>
</ul>
......
{% extends "stock/stock_menu.html" %}
{% load static %}
{% block additionnal_css %}
<link rel="stylesheet" href="{% static 'css/datatables/jquery.dataTables.css' %}">
{% endblock %}
{% block additionnal_scripts %}
<script type="text/javascript" src="{% static 'js/datatables/jquery.dataTables.min.js' %}"></script>
<script type="text/javascript" src="{% static 'js/datatables/dataTables.plugins.js' %}"></script>
<script type="text/javascript" src="{% static 'js/datatables/datatables.buttons.min.js' %}"></script>
<script type="text/javascript" src="{% static 'js/datatables/buttons.html5.min.js' %}"></script>
<script type="text/javascript" src="{% static 'js/datatables/jszip.min.js' %}"></script>
<script type="text/javascript" src="{% static 'js/stock_values.js' %}"></script>
{% endblock %}
{% block content %}
<h1>Stock valorisé</h1>
<br>
<div class="main">
<table id="tableArticle" class="display" width="95%" cellspacing="0" ></table>
</div>
<br/>
<br/>
<script src="{% static "js/all_common.js" %}?v=1651853225"></script>
<script src="{% static "js/common.js" %}?v=1651853225"></script>
{% endblock %}
......@@ -24,6 +24,11 @@
<p><button type="submit">Connexion</button></p>
</form>
<p style="color:red;">{{msg}}</p>
{% if permanent_message %}
<div id="permanent_message">
{{permanent_message}}
</div>
{% endif %}
<!--<p><a href="oubli_pass">Mot de passe oublié</a></p>-->
<script>
try {
......
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