tup = login_url, REDIRECT_FIELD_NAME, path
messages.add_message(request, messages.ERROR, "Votre compte ne permet pas d'accéder à cette partie de l'application.")
return HttpResponseRedirect('%s?%s=%s' % tup)
+
+ def in_drh_or_admin(user):
+ """
+ Teste si un user Django fait parti du groupe DRH, DRH2 ou s'il est admin
+ """
+ groups = user.groups.all()
+ if user.is_superuser or \
+ grp_drh in groups or \
+ grp_drh2 in groups:
+ return True
+ else:
+ return False
+
+ def drh_or_admin_required(fn):
+ """
+ Teste si un user Django fait parti du groupe DRH, DRH2 ou s'il est admin
+ """
+ def inner(request, *args, **kwargs):
+ user = request.user
+ if in_drh_or_admin(user):
+ return fn(request, *args, **kwargs)
+ msg = u"Votre compte ne permet pas d'accéder à " \
+ u"cette partie de l'application."
+ return redirect_interdiction(request, msg)
+ return inner
+
+ def region_protected(model):
+ def wrapper(func):
+ def wrapped(request, id):
+ if request.user.is_superuser:
+ return func(request, id)
+ user_groups = request.user.groups.all()
+ if grp_drh in user_groups:
+ return func(request, id)
+ if grp_correspondants_rh in user_groups:
+ employe = get_employe_from_user(request.user)
+ q = Q(**{
+ model.prefix_implantation: employe.implantation.region
+ })
+ qs = model.objects.filter(q)
+ if int(id) in [o.id for o in qs]:
+ return func(request, id)
+ return redirect_interdiction(request)
+ return wrapped
+ return wrapper
++
++def in_one_of_group(groups):
++ """
++ Test si le user appartient au moins 1 des ces groupes
++ """
++ def wrapper(fn):
++ def wrapped(request, *args, **kwargs):
++ user_groups = request.user.groups.all()
++ for g in user_groups:
++ if g in groups:
++ return fn(request, *args, **kwargs)
++ msg = u"Votre compte ne permet pas d'accéder à cette partie de l'application."
++ return redirect_interdiction(request, msg)
++ return wrapped
++ return wrapper
from django.utils.translation import ugettext_lazy as _
from admin_tools.menu import items, Menu
- from project.rh.decorators import in_drh_or_admin
- from project.rh import groups
+
+ from project.decorators import in_drh_or_admin
++from project import groups
++
class CustomMenu(Menu):
"""
from django.db.models import Q, Count
from django.template.defaultfilters import date
+ from ajax_select import make_ajax_form
+
+ from auf.django.metadata.admin import \
+ AUFMetadataAdminMixin, AUFMetadataInlineAdminMixin, \
+ AUF_METADATA_READONLY_FIELDS
import auf.django.references.models as ref
- import models as rh
- from forms import \
+
++from project import groups
+ from project.decorators import in_drh_or_admin
-from project.groups import grp_correspondants_rh
+ from project.groups import get_employe_from_user
+
+ import project.rh.models as rh
+ from project.rh.forms import \
ContratForm, AyantDroitForm, EmployeAdminForm, AjaxSelect, DossierForm
- from dae.utils import get_employe_from_user
- from change_list import ChangeList
- from project.rh import groups
- from decorators import in_drh_or_admin
+ from project.rh.change_list import ChangeList
class BaseAdmin(admin.ModelAdmin):
from django.template import Library
from django.utils.http import urlencode
- from datamaster_modeles.models import Implantation, Region
- from rh.models import TypeContrat
- from project.rh import groups
- # pas de reference a DAE devrait etre refactorisé
- from dae.utils import get_employe_from_user
+ from auf.django.references.models import Implantation, Region
+
-from project.rh.models import TypeContrat
++from project import groups
++from project.groups import get_employe_from_user
+
++from project.rh.models import TypeContrat
register = Library()
@register.inclusion_tag('admin/filter.html', takes_context=True)
def filter_region_contrat(context):
- return {
- 'title': u"région",
- 'choices': prepare_choices(
- Region.objects.values_list('id', 'nom'),
- 'dossier__poste__implantation__region', context,
- remove=['pays', 'nord_sud']
- )
- }
+ request = context['request']
+ user_groups = request.user.groups.all()
+ if groups.grp_correspondants_rh in user_groups or\
+ groups.grp_administrateurs in user_groups or\
+ groups.grp_directeurs_bureau in user_groups:
+ employe = get_employe_from_user(request.user)
+ regions = Region.objects.filter(id=employe.implantation.region.id)
+ else:
+ regions = Region.objects.all()
+ return {'title': u"région",
+ 'choices': prepare_choices(regions.values_list('id', 'nom'), 'dossier__poste__implantation__region', context, remove=['pays', 'nord_sud'])}
+
@register.inclusion_tag('admin/filter.html', takes_context=True)
def filter_region_dossier(context):
- return {'title': u"région",
- 'choices': prepare_choices(Region.objects.values_list('id', 'nom'), 'poste__implantation__region', context, remove=['pays', 'nord_sud'])}
+ return {
+ 'title': u"région",
+ 'choices': prepare_choices(
+ Region.objects.values_list('id', 'nom'),
+ 'poste__implantation__region', context,
+ remove=['pays', 'nord_sud']
+ )
+ }
+
@register.inclusion_tag('admin/filter.html', takes_context=True)
def filter_implantation_dossier(context):
import StringIO
import pygraphviz as pgv
- from datamaster_modeles import models as ref
- from django.core.urlresolvers import reverse
- from django.db.models import Q
- from django.utils.encoding import smart_str
- from django.shortcuts import render_to_response, get_object_or_404
- from django.template import RequestContext
- from django.http import HttpResponse
+
from django import forms
+ from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.core.servers.basehttp import FileWrapper
+ from django.core.urlresolvers import reverse
+ from django.db.models import Q
+ from django.http import HttpResponse
+ from django.shortcuts import render, get_object_or_404
- from rh import models as rh
- from rh.lib import calc_remun
- from project.rh.decorators import drh_or_admin_required, in_one_of_group
- from rh.templatetags.rapports import SortHeaders
- from rh.change_list import RechercheTemporelle
- from rh import graph as rh_graph
- from rh.masse_salariale import MasseSalariale
-
- # pas de reference a DAE devrait etre refactorisé
- from dae.utils import get_employe_from_user
- from dae.decorators import redirect_interdiction
- from django.conf import settings
- from project.rh.decorators import in_drh_or_admin
- from project.rh import groups
+ from auf.django.references import models as ref
+
++from project import groups
++from project.decorators import drh_or_admin_required, in_one_of_group
+ from project.decorators import redirect_interdiction
-from project.decorators import drh_or_admin_required
+ from project.decorators import region_protected
+ from project.groups import get_employe_from_user
-from project.groups import grp_drh, grp_correspondants_rh
+
+ from project.rh import models as rh
+ from project.rh import graph as rh_graph
+ from project.rh.change_list import RechercheTemporelle
+ from project.rh.lib import calc_remun, get_lookup_params
+ from project.rh.masse_salariale import MasseSalariale
+ from project.rh.templatetags.rapports import SortHeaders
@login_required
+@drh_or_admin_required
def profil(request):
"""Profil personnel de l'employé - éditable"""
- rc = RequestContext(request)
- c = {}
-
- employe = rc['this_employe']
-
- c['user'] = request.user
- c['employe'] = employe
- return render_to_response('rh/profil.html', c, rc)
+ employe = get_employe_from_user(user)
+ c = {
+ 'user': request.user,
+ 'employe': employe,
+ }
+ return render(request, 'rh/profil.html', c)
@login_required
@login_required
-@drh_or_admin_required
+@in_one_of_group((groups.grp_correspondants_rh,
+ groups.grp_administrateurs,
+ groups.grp_directeurs_bureau,
+ groups.grp_drh,
+ groups.grp_drh2))
- def rapports_employe_sans_contrat(request):
-
- lookup_params = dict(request.GET.items())
- if 'ot' in lookup_params:
- del lookup_params['ot']
- if 'o' in lookup_params:
- del lookup_params['o']
-
- for key, value in lookup_params.items():
- if not isinstance(key, str):
- # 'key' will be used as a keyword argument later, so Python
- # requires it to be a string.
- del lookup_params[key]
- lookup_params[smart_str(key)] = value
-
- employes_query = rh.Employe.objects
- if 'o' in request.GET:
- employes_query = employes_query.order_by(
- ('-' if request.GET.get('ot') == "desc" else '') + request.GET['o']
- )
-
- employes = {}
+ def rapports_employes_sans_contrat(request):
+ lookup_params = get_lookup_params(request)
++ # régionalisation
+ user_groups = request.user.groups.all()
+ q_region = Q()
+ if groups.grp_correspondants_rh in user_groups or\
+ groups.grp_administrateurs in user_groups or\
+ groups.grp_directeurs_bureau in user_groups:
+ employe = get_employe_from_user(request.user)
+ q_region = Q(poste__implantation__region=employe.implantation.region)
+
- dossiers_en_cours = rh.Dossier.objects.filter(q_region & (
- Q(date_fin=None) | Q(date_fin__gt=date.today()))
- )
- tous_contrats_echus = rh.Contrat.objects.filter(
- date_fin__lt=date.today(), dossier__in=dossiers_en_cours
- )
- contrats = tous_contrats_echus.filter(**lookup_params).all()
- for c in contrats:
- if c.dossier.employe.id not in employes.keys():
- employes[c.dossier.employe.id] = {
- 'employe': c.dossier.employe,
- 'dossiers': []
- }
- employes[c.dossier.employe.id]['dossiers'] += [c.dossier]
+ # contrats échus
+ contrats_echus = rh.Contrat.objects.filter(
+ date_fin__lt=date.today()
+ ).filter(
+ **lookup_params
+ )
+
+ # dossiers en cours sans contrat
- dossiers_sans_contrat = rh.Dossier.objects.filter(
- Q(date_fin=None) | Q(date_fin__gt=date.today()),
++ dossiers_sans_contrat = rh.Dossier.objects.filter(q_region & (
++ Q(date_fin=None) | Q(date_fin__gt=date.today())),
+ ).exclude(
+ date_debut__gt=date.today()
+ ).filter(
+ rh_contrats__in=contrats_echus
+ )
+
+ # employés sans contrat
+ employes = rh.Employe.objects.filter(rh_dossiers__in=dossiers_sans_contrat).distinct()
+ if 'o' in request.GET:
+ employes = employes.order_by(
+ ('-' if request.GET.get('ot') == "desc" else '') + request.GET['o']
+ )
+ # affichage
headers = [
("id", u"# de l'employé"),
- ("nom", u"Nom"),
- ("prenom", u"Prénom"),
- ("dossier", u"Dossiers"),
+ ("nom", u"Employé"),
+ ("dossier", u"Dossier : Poste"),
+ ("dossier_date_debut", u"Début occupation poste"),
+ ("dossier_date_fin", u"Fin occupation poste"),
]
h = SortHeaders(
request, headers, order_field_type="ot", order_field="o",
),
'media_url': settings.PRIVE_MEDIA_URL,
}
- return render_to_response(
- 'admin/rh/poste/apercu.html', c, RequestContext(request)
- )
+ return render(request, 'admin/rh/poste/apercu.html', c)
-
+@region_protected(rh.Employe)
def employe_apercu(request, employe_id):
employe = get_object_or_404(rh.Employe, pk=employe_id)
user_groups = request.user.groups.all()
ADMIN_TOOLS_MENU = 'project.menu.CustomMenu'
AJAX_LOOKUP_CHANNELS = {
- 'responsables' : ('dae.catalogues', 'Responsable'),
- 'dossiers' : ('dae.catalogues', 'Dossier'),
- 'dae_postes' : ('dae.catalogues', 'Poste'),
- 'pays' : ('rh.catalogues', 'Pays'),
- 'implantations' : ('rh.catalogues', 'Implantation'),
- 'typepostes' : ('rh.catalogues', 'TypePoste'),
- 'postes' : ('rh.catalogues', 'Poste'),
- 'valeurpoints' : ('rh.catalogues', 'ValeurPoint'),
- 'employes' : ('rh.catalogues', 'Employe'),
- 'dossiers' : ('rh.catalogues', 'Dossier'),
+ 'responsables': ('project.dae.catalogues', 'Responsable'),
+ 'dossiers': ('project.dae.catalogues', 'Dossier'),
+ 'dae_postes': ('project.dae.catalogues', 'Poste'),
+ 'pays': ('project.rh.catalogues', 'Pays'),
+ 'implantations': ('project.rh.catalogues', 'Implantation'),
+ 'typepostes': ('project.rh.catalogues', 'TypePoste'),
+ 'postes': ('project.rh.catalogues', 'Poste'),
+ 'valeurpoints': ('project.rh.catalogues', 'ValeurPoint'),
+ 'employes': ('project.rh.catalogues', 'Employe'),
+ 'dossiers': ('project.rh.catalogues', 'Dossier'),
}
-AJAX_SELECT_BOOTSTRAP = True
AJAX_SELECT_INLINES = 'inline'
# django-sendfile
SENDFILE_BACKEND = 'sendfile.backends.simple'
+ QBE_DISPLAY_DATABASES = False
+
+ # Il est *très* important de respecter la case.
+ QBE_CUSTOM_MODELS = {'Rh': {
+ 'Employe': {},
+ 'Poste': {},
+ 'Dossier': {},
+ 'Remuneration': {},
+ 'Contrat': {},
+ }}
+
+ QBE_ALLOWED_FIELDS = {'Rh': {
+ 'Employe': [
+ 'nom', 'prenom', 'genre', 'date_naissance', 'situation_familiale',
+ 'date_entree'
+ ],
+ 'Poste': ['nom', 'date_debut', 'date_fin'],
+ 'Dossier': [
+ 'statut_residence', 'regime_travail',
+ 'regime_travail_nb_heure_semaine', 'date_debut', 'date_fin'
+ ],
+ 'Remuneration': ['montant', 'date_debut', 'date_fin'],
+ 'Contrat': ['date_debut', 'date_fin'],
+ }}
++
+SOUTH_TESTS_MIGRATE = False
auf.django.emploi = 1.0dev
auf.django.metadata = 0.6dev
auf.django.permissions = 0.1
-auf.django.references = 0.11
++auf.django.references = 0.17
auf.django.skin = 1.5
auf.django.workflow = 0.15dev
- auf.django.references = 0.17
odfpy = 0.9.4
pygraphviz = 0.36