mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-26 06:32:26 +00:00
Merge branch '210-use-black-for-formatting' into 'dev'
Resolve "Use black for formatting" See merge request federez/re2o!468
This commit is contained in:
commit
540a8d0531
515 changed files with 16814 additions and 13681 deletions
17
api/acl.py
17
api/acl.py
|
@ -40,14 +40,14 @@ def _create_api_permission():
|
||||||
"""
|
"""
|
||||||
api_content_type, created = ContentType.objects.get_or_create(
|
api_content_type, created = ContentType.objects.get_or_create(
|
||||||
app_label=settings.API_CONTENT_TYPE_APP_LABEL,
|
app_label=settings.API_CONTENT_TYPE_APP_LABEL,
|
||||||
model=settings.API_CONTENT_TYPE_MODEL
|
model=settings.API_CONTENT_TYPE_MODEL,
|
||||||
)
|
)
|
||||||
if created:
|
if created:
|
||||||
api_content_type.save()
|
api_content_type.save()
|
||||||
api_permission, created = Permission.objects.get_or_create(
|
api_permission, created = Permission.objects.get_or_create(
|
||||||
name=settings.API_PERMISSION_NAME,
|
name=settings.API_PERMISSION_NAME,
|
||||||
content_type=api_content_type,
|
content_type=api_content_type,
|
||||||
codename=settings.API_PERMISSION_CODENAME
|
codename=settings.API_PERMISSION_CODENAME,
|
||||||
)
|
)
|
||||||
if created:
|
if created:
|
||||||
api_permission.save()
|
api_permission.save()
|
||||||
|
@ -67,10 +67,13 @@ def can_view(user):
|
||||||
viewing is granted and msg is a message (can be None).
|
viewing is granted and msg is a message (can be None).
|
||||||
"""
|
"""
|
||||||
kwargs = {
|
kwargs = {
|
||||||
'app_label': settings.API_CONTENT_TYPE_APP_LABEL,
|
"app_label": settings.API_CONTENT_TYPE_APP_LABEL,
|
||||||
'codename': settings.API_PERMISSION_CODENAME
|
"codename": settings.API_PERMISSION_CODENAME,
|
||||||
}
|
}
|
||||||
permission = '%(app_label)s.%(codename)s' % kwargs
|
permission = "%(app_label)s.%(codename)s" % kwargs
|
||||||
can = user.has_perm(permission)
|
can = user.has_perm(permission)
|
||||||
return can, None if can else _("You don't have the right to see this"
|
return (
|
||||||
" application."), (permission,)
|
can,
|
||||||
|
None if can else _("You don't have the right to see this" " application."),
|
||||||
|
(permission,),
|
||||||
|
)
|
||||||
|
|
|
@ -41,9 +41,7 @@ class ExpiringTokenAuthentication(TokenAuthentication):
|
||||||
user, token = base.authenticate_credentials(key)
|
user, token = base.authenticate_credentials(key)
|
||||||
|
|
||||||
# Check that the genration time of the token is not too old
|
# Check that the genration time of the token is not too old
|
||||||
token_duration = datetime.timedelta(
|
token_duration = datetime.timedelta(seconds=settings.API_TOKEN_DURATION)
|
||||||
seconds=settings.API_TOKEN_DURATION
|
|
||||||
)
|
|
||||||
utc_now = datetime.datetime.now(datetime.timezone.utc)
|
utc_now = datetime.datetime.now(datetime.timezone.utc)
|
||||||
if token.created < utc_now - token_duration:
|
if token.created < utc_now - token_duration:
|
||||||
raise exceptions.AuthenticationFailed(_("The token has expired."))
|
raise exceptions.AuthenticationFailed(_("The token has expired."))
|
||||||
|
|
|
@ -38,8 +38,9 @@ class PageSizedPagination(pagination.PageNumberPagination):
|
||||||
max_page_size: The maximum number of results a page can output no
|
max_page_size: The maximum number of results a page can output no
|
||||||
matter what is requested.
|
matter what is requested.
|
||||||
"""
|
"""
|
||||||
page_size_query_param = 'page_size'
|
|
||||||
all_pages_strings = ('all',)
|
page_size_query_param = "page_size"
|
||||||
|
all_pages_strings = ("all",)
|
||||||
max_page_size = 10000
|
max_page_size = 10000
|
||||||
|
|
||||||
def get_page_size(self, request):
|
def get_page_size(self, request):
|
||||||
|
|
|
@ -55,17 +55,21 @@ def _get_param_in_view(view, param_name):
|
||||||
AssertionError: None of the getter function or the attribute are
|
AssertionError: None of the getter function or the attribute are
|
||||||
defined in the view.
|
defined in the view.
|
||||||
"""
|
"""
|
||||||
assert hasattr(view, 'get_' + param_name) \
|
assert (
|
||||||
or getattr(view, param_name, None) is not None, (
|
hasattr(view, "get_" + param_name)
|
||||||
'cannot apply {} on a view that does not set '
|
or getattr(view, param_name, None) is not None
|
||||||
'`.{}` or have a `.get_{}()` method.'
|
), (
|
||||||
).format(self.__class__.__name__, param_name, param_name)
|
"cannot apply {} on a view that does not set "
|
||||||
|
"`.{}` or have a `.get_{}()` method."
|
||||||
|
).format(
|
||||||
|
self.__class__.__name__, param_name, param_name
|
||||||
|
)
|
||||||
|
|
||||||
if hasattr(view, 'get_' + param_name):
|
if hasattr(view, "get_" + param_name):
|
||||||
param = getattr(view, 'get_' + param_name)()
|
param = getattr(view, "get_" + param_name)()
|
||||||
assert param is not None, (
|
assert param is not None, ("{}.get_{}() returned None").format(
|
||||||
'{}.get_{}() returned None'
|
view.__class__.__name__, param_name
|
||||||
).format(view.__class__.__name__, param_name)
|
)
|
||||||
return param
|
return param
|
||||||
return getattr(view, param_name)
|
return getattr(view, param_name)
|
||||||
|
|
||||||
|
@ -97,7 +101,7 @@ class ACLPermission(permissions.BasePermission):
|
||||||
rest_framework.exception.MethodNotAllowed: The requested method
|
rest_framework.exception.MethodNotAllowed: The requested method
|
||||||
is not allowed for this view.
|
is not allowed for this view.
|
||||||
"""
|
"""
|
||||||
perms_map = _get_param_in_view(view, 'perms_map')
|
perms_map = _get_param_in_view(view, "perms_map")
|
||||||
|
|
||||||
if method not in perms_map:
|
if method not in perms_map:
|
||||||
raise exceptions.MethodNotAllowed(method)
|
raise exceptions.MethodNotAllowed(method)
|
||||||
|
@ -123,7 +127,7 @@ class ACLPermission(permissions.BasePermission):
|
||||||
"""
|
"""
|
||||||
# Workaround to ensure ACLPermissions are not applied
|
# Workaround to ensure ACLPermissions are not applied
|
||||||
# to the root view when using DefaultRouter.
|
# to the root view when using DefaultRouter.
|
||||||
if getattr(view, '_ignore_model_permissions', False):
|
if getattr(view, "_ignore_model_permissions", False):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if not request.user or not request.user.is_authenticated:
|
if not request.user or not request.user.is_authenticated:
|
||||||
|
@ -148,22 +152,22 @@ class AutodetectACLPermission(permissions.BasePermission):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
perms_map = {
|
perms_map = {
|
||||||
'GET': [can_see_api, lambda model: model.can_view_all],
|
"GET": [can_see_api, lambda model: model.can_view_all],
|
||||||
'OPTIONS': [can_see_api, lambda model: model.can_view_all],
|
"OPTIONS": [can_see_api, lambda model: model.can_view_all],
|
||||||
'HEAD': [can_see_api, lambda model: model.can_view_all],
|
"HEAD": [can_see_api, lambda model: model.can_view_all],
|
||||||
'POST': [can_see_api, lambda model: model.can_create],
|
"POST": [can_see_api, lambda model: model.can_create],
|
||||||
'PUT': [], # No restrictions, apply to objects
|
"PUT": [], # No restrictions, apply to objects
|
||||||
'PATCH': [], # No restrictions, apply to objects
|
"PATCH": [], # No restrictions, apply to objects
|
||||||
'DELETE': [], # No restrictions, apply to objects
|
"DELETE": [], # No restrictions, apply to objects
|
||||||
}
|
}
|
||||||
perms_obj_map = {
|
perms_obj_map = {
|
||||||
'GET': [can_see_api, lambda obj: obj.can_view],
|
"GET": [can_see_api, lambda obj: obj.can_view],
|
||||||
'OPTIONS': [can_see_api, lambda obj: obj.can_view],
|
"OPTIONS": [can_see_api, lambda obj: obj.can_view],
|
||||||
'HEAD': [can_see_api, lambda obj: obj.can_view],
|
"HEAD": [can_see_api, lambda obj: obj.can_view],
|
||||||
'POST': [], # No restrictions, apply to models
|
"POST": [], # No restrictions, apply to models
|
||||||
'PUT': [can_see_api, lambda obj: obj.can_edit],
|
"PUT": [can_see_api, lambda obj: obj.can_edit],
|
||||||
'PATCH': [can_see_api, lambda obj: obj.can_edit],
|
"PATCH": [can_see_api, lambda obj: obj.can_edit],
|
||||||
'DELETE': [can_see_api, lambda obj: obj.can_delete],
|
"DELETE": [can_see_api, lambda obj: obj.can_delete],
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_required_permissions(self, method, model):
|
def get_required_permissions(self, method, model):
|
||||||
|
@ -210,7 +214,7 @@ class AutodetectACLPermission(permissions.BasePermission):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _queryset(view):
|
def _queryset(view):
|
||||||
return _get_param_in_view(view, 'queryset')
|
return _get_param_in_view(view, "queryset")
|
||||||
|
|
||||||
def has_permission(self, request, view):
|
def has_permission(self, request, view):
|
||||||
"""Check that the user has the model-based permissions to perform
|
"""Check that the user has the model-based permissions to perform
|
||||||
|
@ -232,7 +236,7 @@ class AutodetectACLPermission(permissions.BasePermission):
|
||||||
"""
|
"""
|
||||||
# Workaround to ensure ACLPermissions are not applied
|
# Workaround to ensure ACLPermissions are not applied
|
||||||
# to the root view when using DefaultRouter.
|
# to the root view when using DefaultRouter.
|
||||||
if getattr(view, '_ignore_model_permissions', False):
|
if getattr(view, "_ignore_model_permissions", False):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if not request.user or not request.user.is_authenticated:
|
if not request.user or not request.user.is_authenticated:
|
||||||
|
@ -274,7 +278,7 @@ class AutodetectACLPermission(permissions.BasePermission):
|
||||||
# to make another lookup.
|
# to make another lookup.
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
read_perms = self.get_required_object_permissions('GET', obj)
|
read_perms = self.get_required_object_permissions("GET", obj)
|
||||||
if not read_perms(request.user)[0]:
|
if not read_perms(request.user)[0]:
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ class AllViewsRouter(DefaultRouter):
|
||||||
Returns:
|
Returns:
|
||||||
The name to use for this route.
|
The name to use for this route.
|
||||||
"""
|
"""
|
||||||
return pattern.split('/')[-1]
|
return pattern.split("/")[-1]
|
||||||
|
|
||||||
def get_api_root_view(self, schema_urls=None, api_urls=None):
|
def get_api_root_view(self, schema_urls=None, api_urls=None):
|
||||||
"""Create a class-based view to use as the API root.
|
"""Create a class-based view to use as the API root.
|
||||||
|
@ -102,12 +102,10 @@ class AllViewsRouter(DefaultRouter):
|
||||||
if schema_urls and self.schema_title:
|
if schema_urls and self.schema_title:
|
||||||
view_renderers += list(self.schema_renderers)
|
view_renderers += list(self.schema_renderers)
|
||||||
schema_generator = SchemaGenerator(
|
schema_generator = SchemaGenerator(
|
||||||
title=self.schema_title,
|
title=self.schema_title, patterns=schema_urls
|
||||||
patterns=schema_urls
|
|
||||||
)
|
)
|
||||||
schema_media_types = [
|
schema_media_types = [
|
||||||
renderer.media_type
|
renderer.media_type for renderer in self.schema_renderers
|
||||||
for renderer in self.schema_renderers
|
|
||||||
]
|
]
|
||||||
|
|
||||||
class APIRoot(views.APIView):
|
class APIRoot(views.APIView):
|
||||||
|
@ -128,14 +126,14 @@ class AllViewsRouter(DefaultRouter):
|
||||||
namespace = request.resolver_match.namespace
|
namespace = request.resolver_match.namespace
|
||||||
for key, url_name in api_root_dict.items():
|
for key, url_name in api_root_dict.items():
|
||||||
if namespace:
|
if namespace:
|
||||||
url_name = namespace + ':' + url_name
|
url_name = namespace + ":" + url_name
|
||||||
try:
|
try:
|
||||||
ret[key] = reverse(
|
ret[key] = reverse(
|
||||||
url_name,
|
url_name,
|
||||||
args=args,
|
args=args,
|
||||||
kwargs=kwargs,
|
kwargs=kwargs,
|
||||||
request=request,
|
request=request,
|
||||||
format=kwargs.get('format', None)
|
format=kwargs.get("format", None),
|
||||||
)
|
)
|
||||||
except NoReverseMatch:
|
except NoReverseMatch:
|
||||||
# Don't bail out if eg. no list routes exist, only detail routes.
|
# Don't bail out if eg. no list routes exist, only detail routes.
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -24,28 +24,24 @@
|
||||||
|
|
||||||
# RestFramework config for API
|
# RestFramework config for API
|
||||||
REST_FRAMEWORK = {
|
REST_FRAMEWORK = {
|
||||||
'URL_FIELD_NAME': 'api_url',
|
"URL_FIELD_NAME": "api_url",
|
||||||
'DEFAULT_AUTHENTICATION_CLASSES': (
|
"DEFAULT_AUTHENTICATION_CLASSES": (
|
||||||
'api.authentication.ExpiringTokenAuthentication',
|
"api.authentication.ExpiringTokenAuthentication",
|
||||||
'rest_framework.authentication.SessionAuthentication',
|
"rest_framework.authentication.SessionAuthentication",
|
||||||
),
|
),
|
||||||
'DEFAULT_PERMISSION_CLASSES': (
|
"DEFAULT_PERMISSION_CLASSES": ("api.permissions.AutodetectACLPermission",),
|
||||||
'api.permissions.AutodetectACLPermission',
|
"DEFAULT_PAGINATION_CLASS": "api.pagination.PageSizedPagination",
|
||||||
),
|
"PAGE_SIZE": 100,
|
||||||
'DEFAULT_PAGINATION_CLASS': 'api.pagination.PageSizedPagination',
|
|
||||||
'PAGE_SIZE': 100
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# API permission settings
|
# API permission settings
|
||||||
API_CONTENT_TYPE_APP_LABEL = 'api'
|
API_CONTENT_TYPE_APP_LABEL = "api"
|
||||||
API_CONTENT_TYPE_MODEL = 'api'
|
API_CONTENT_TYPE_MODEL = "api"
|
||||||
API_PERMISSION_NAME = 'Can use the API'
|
API_PERMISSION_NAME = "Can use the API"
|
||||||
API_PERMISSION_CODENAME = 'use_api'
|
API_PERMISSION_CODENAME = "use_api"
|
||||||
|
|
||||||
# Activate token authentication
|
# Activate token authentication
|
||||||
API_APPS = (
|
API_APPS = ("rest_framework.authtoken",)
|
||||||
'rest_framework.authtoken',
|
|
||||||
)
|
|
||||||
|
|
||||||
# The expiration time for an authentication token
|
# The expiration time for an authentication token
|
||||||
API_TOKEN_DURATION = 86400 # 24 hours
|
API_TOKEN_DURATION = 86400 # 24 hours
|
||||||
|
|
523
api/tests.py
523
api/tests.py
|
@ -50,171 +50,170 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
superuser: A superuser (with all permissions) used for the tests and
|
superuser: A superuser (with all permissions) used for the tests and
|
||||||
initialized at the beggining of this test case.
|
initialized at the beggining of this test case.
|
||||||
"""
|
"""
|
||||||
no_auth_endpoints = [
|
|
||||||
'/api/'
|
no_auth_endpoints = ["/api/"]
|
||||||
]
|
|
||||||
auth_no_perm_endpoints = []
|
auth_no_perm_endpoints = []
|
||||||
auth_perm_endpoints = [
|
auth_perm_endpoints = [
|
||||||
'/api/cotisations/article/',
|
"/api/cotisations/article/",
|
||||||
'/api/cotisations/article/1/',
|
"/api/cotisations/article/1/",
|
||||||
'/api/cotisations/banque/',
|
"/api/cotisations/banque/",
|
||||||
'/api/cotisations/banque/1/',
|
"/api/cotisations/banque/1/",
|
||||||
'/api/cotisations/cotisation/',
|
"/api/cotisations/cotisation/",
|
||||||
'/api/cotisations/cotisation/1/',
|
"/api/cotisations/cotisation/1/",
|
||||||
'/api/cotisations/facture/',
|
"/api/cotisations/facture/",
|
||||||
'/api/cotisations/facture/1/',
|
"/api/cotisations/facture/1/",
|
||||||
'/api/cotisations/paiement/',
|
"/api/cotisations/paiement/",
|
||||||
'/api/cotisations/paiement/1/',
|
"/api/cotisations/paiement/1/",
|
||||||
'/api/cotisations/vente/',
|
"/api/cotisations/vente/",
|
||||||
'/api/cotisations/vente/1/',
|
"/api/cotisations/vente/1/",
|
||||||
'/api/machines/domain/',
|
"/api/machines/domain/",
|
||||||
'/api/machines/domain/1/',
|
"/api/machines/domain/1/",
|
||||||
'/api/machines/extension/',
|
"/api/machines/extension/",
|
||||||
'/api/machines/extension/1/',
|
"/api/machines/extension/1/",
|
||||||
'/api/machines/interface/',
|
"/api/machines/interface/",
|
||||||
'/api/machines/interface/1/',
|
"/api/machines/interface/1/",
|
||||||
'/api/machines/iplist/',
|
"/api/machines/iplist/",
|
||||||
'/api/machines/iplist/1/',
|
"/api/machines/iplist/1/",
|
||||||
'/api/machines/iptype/',
|
"/api/machines/iptype/",
|
||||||
'/api/machines/iptype/1/',
|
"/api/machines/iptype/1/",
|
||||||
'/api/machines/ipv6list/',
|
"/api/machines/ipv6list/",
|
||||||
'/api/machines/ipv6list/1/',
|
"/api/machines/ipv6list/1/",
|
||||||
'/api/machines/machine/',
|
"/api/machines/machine/",
|
||||||
'/api/machines/machine/1/',
|
"/api/machines/machine/1/",
|
||||||
'/api/machines/machinetype/',
|
"/api/machines/machinetype/",
|
||||||
'/api/machines/machinetype/1/',
|
"/api/machines/machinetype/1/",
|
||||||
'/api/machines/mx/',
|
"/api/machines/mx/",
|
||||||
'/api/machines/mx/1/',
|
"/api/machines/mx/1/",
|
||||||
'/api/machines/nas/',
|
"/api/machines/nas/",
|
||||||
'/api/machines/nas/1/',
|
"/api/machines/nas/1/",
|
||||||
'/api/machines/ns/',
|
"/api/machines/ns/",
|
||||||
'/api/machines/ns/1/',
|
"/api/machines/ns/1/",
|
||||||
'/api/machines/ouvertureportlist/',
|
"/api/machines/ouvertureportlist/",
|
||||||
'/api/machines/ouvertureportlist/1/',
|
"/api/machines/ouvertureportlist/1/",
|
||||||
'/api/machines/ouvertureport/',
|
"/api/machines/ouvertureport/",
|
||||||
'/api/machines/ouvertureport/1/',
|
"/api/machines/ouvertureport/1/",
|
||||||
'/api/machines/servicelink/',
|
"/api/machines/servicelink/",
|
||||||
'/api/machines/servicelink/1/',
|
"/api/machines/servicelink/1/",
|
||||||
'/api/machines/service/',
|
"/api/machines/service/",
|
||||||
'/api/machines/service/1/',
|
"/api/machines/service/1/",
|
||||||
'/api/machines/soa/',
|
"/api/machines/soa/",
|
||||||
'/api/machines/soa/1/',
|
"/api/machines/soa/1/",
|
||||||
'/api/machines/srv/',
|
"/api/machines/srv/",
|
||||||
'/api/machines/srv/1/',
|
"/api/machines/srv/1/",
|
||||||
'/api/machines/txt/',
|
"/api/machines/txt/",
|
||||||
'/api/machines/txt/1/',
|
"/api/machines/txt/1/",
|
||||||
'/api/machines/vlan/',
|
"/api/machines/vlan/",
|
||||||
'/api/machines/vlan/1/',
|
"/api/machines/vlan/1/",
|
||||||
'/api/preferences/optionaluser/',
|
"/api/preferences/optionaluser/",
|
||||||
'/api/preferences/optionalmachine/',
|
"/api/preferences/optionalmachine/",
|
||||||
'/api/preferences/optionaltopologie/',
|
"/api/preferences/optionaltopologie/",
|
||||||
'/api/preferences/generaloption/',
|
"/api/preferences/generaloption/",
|
||||||
'/api/preferences/service/',
|
"/api/preferences/service/",
|
||||||
'/api/preferences/service/1/',
|
"/api/preferences/service/1/",
|
||||||
'/api/preferences/assooption/',
|
"/api/preferences/assooption/",
|
||||||
'/api/preferences/homeoption/',
|
"/api/preferences/homeoption/",
|
||||||
'/api/preferences/mailmessageoption/',
|
"/api/preferences/mailmessageoption/",
|
||||||
'/api/topologie/acesspoint/',
|
"/api/topologie/acesspoint/",
|
||||||
# 2nd machine to be create (machines_machine_1, topologie_accesspoint_1)
|
# 2nd machine to be create (machines_machine_1, topologie_accesspoint_1)
|
||||||
'/api/topologie/acesspoint/2/',
|
"/api/topologie/acesspoint/2/",
|
||||||
'/api/topologie/building/',
|
"/api/topologie/building/",
|
||||||
'/api/topologie/building/1/',
|
"/api/topologie/building/1/",
|
||||||
'/api/topologie/constructorswitch/',
|
"/api/topologie/constructorswitch/",
|
||||||
'/api/topologie/constructorswitch/1/',
|
"/api/topologie/constructorswitch/1/",
|
||||||
'/api/topologie/modelswitch/',
|
"/api/topologie/modelswitch/",
|
||||||
'/api/topologie/modelswitch/1/',
|
"/api/topologie/modelswitch/1/",
|
||||||
'/api/topologie/room/',
|
"/api/topologie/room/",
|
||||||
'/api/topologie/room/1/',
|
"/api/topologie/room/1/",
|
||||||
'/api/topologie/server/',
|
"/api/topologie/server/",
|
||||||
# 3rd machine to be create (machines_machine_1, topologie_accesspoint_1,
|
# 3rd machine to be create (machines_machine_1, topologie_accesspoint_1,
|
||||||
# topologie_server_1)
|
# topologie_server_1)
|
||||||
'/api/topologie/server/3/',
|
"/api/topologie/server/3/",
|
||||||
'/api/topologie/stack/',
|
"/api/topologie/stack/",
|
||||||
'/api/topologie/stack/1/',
|
"/api/topologie/stack/1/",
|
||||||
'/api/topologie/switch/',
|
"/api/topologie/switch/",
|
||||||
# 4th machine to be create (machines_machine_1, topologie_accesspoint_1,
|
# 4th machine to be create (machines_machine_1, topologie_accesspoint_1,
|
||||||
# topologie_server_1, topologie_switch_1)
|
# topologie_server_1, topologie_switch_1)
|
||||||
'/api/topologie/switch/4/',
|
"/api/topologie/switch/4/",
|
||||||
'/api/topologie/switchbay/',
|
"/api/topologie/switchbay/",
|
||||||
'/api/topologie/switchbay/1/',
|
"/api/topologie/switchbay/1/",
|
||||||
'/api/topologie/switchport/',
|
"/api/topologie/switchport/",
|
||||||
'/api/topologie/switchport/1/',
|
"/api/topologie/switchport/1/",
|
||||||
'/api/topologie/switchport/2/',
|
"/api/topologie/switchport/2/",
|
||||||
'/api/topologie/switchport/3/',
|
"/api/topologie/switchport/3/",
|
||||||
'/api/users/adherent/',
|
"/api/users/adherent/",
|
||||||
# 3rd user to be create (stduser, superuser, users_adherent_1)
|
# 3rd user to be create (stduser, superuser, users_adherent_1)
|
||||||
'/api/users/adherent/3/',
|
"/api/users/adherent/3/",
|
||||||
'/api/users/ban/',
|
"/api/users/ban/",
|
||||||
'/api/users/ban/1/',
|
"/api/users/ban/1/",
|
||||||
'/api/users/club/',
|
"/api/users/club/",
|
||||||
# 4th user to be create (stduser, superuser, users_adherent_1,
|
# 4th user to be create (stduser, superuser, users_adherent_1,
|
||||||
# users_club_1)
|
# users_club_1)
|
||||||
'/api/users/club/4/',
|
"/api/users/club/4/",
|
||||||
'/api/users/listright/',
|
"/api/users/listright/",
|
||||||
# TODO: Merge !145
|
# TODO: Merge !145
|
||||||
# '/api/users/listright/1/',
|
# '/api/users/listright/1/',
|
||||||
'/api/users/school/',
|
"/api/users/school/",
|
||||||
'/api/users/school/1/',
|
"/api/users/school/1/",
|
||||||
'/api/users/serviceuser/',
|
"/api/users/serviceuser/",
|
||||||
'/api/users/serviceuser/1/',
|
"/api/users/serviceuser/1/",
|
||||||
'/api/users/shell/',
|
"/api/users/shell/",
|
||||||
'/api/users/shell/1/',
|
"/api/users/shell/1/",
|
||||||
'/api/users/user/',
|
"/api/users/user/",
|
||||||
'/api/users/user/1/',
|
"/api/users/user/1/",
|
||||||
'/api/users/whitelist/',
|
"/api/users/whitelist/",
|
||||||
'/api/users/whitelist/1/',
|
"/api/users/whitelist/1/",
|
||||||
'/api/dns/zones/',
|
"/api/dns/zones/",
|
||||||
'/api/dhcp/hostmacip/',
|
"/api/dhcp/hostmacip/",
|
||||||
'/api/mailing/standard',
|
"/api/mailing/standard",
|
||||||
'/api/mailing/club',
|
"/api/mailing/club",
|
||||||
'/api/services/regen/',
|
"/api/services/regen/",
|
||||||
]
|
]
|
||||||
not_found_endpoints = [
|
not_found_endpoints = [
|
||||||
'/api/cotisations/article/4242/',
|
"/api/cotisations/article/4242/",
|
||||||
'/api/cotisations/banque/4242/',
|
"/api/cotisations/banque/4242/",
|
||||||
'/api/cotisations/cotisation/4242/',
|
"/api/cotisations/cotisation/4242/",
|
||||||
'/api/cotisations/facture/4242/',
|
"/api/cotisations/facture/4242/",
|
||||||
'/api/cotisations/paiement/4242/',
|
"/api/cotisations/paiement/4242/",
|
||||||
'/api/cotisations/vente/4242/',
|
"/api/cotisations/vente/4242/",
|
||||||
'/api/machines/domain/4242/',
|
"/api/machines/domain/4242/",
|
||||||
'/api/machines/extension/4242/',
|
"/api/machines/extension/4242/",
|
||||||
'/api/machines/interface/4242/',
|
"/api/machines/interface/4242/",
|
||||||
'/api/machines/iplist/4242/',
|
"/api/machines/iplist/4242/",
|
||||||
'/api/machines/iptype/4242/',
|
"/api/machines/iptype/4242/",
|
||||||
'/api/machines/ipv6list/4242/',
|
"/api/machines/ipv6list/4242/",
|
||||||
'/api/machines/machine/4242/',
|
"/api/machines/machine/4242/",
|
||||||
'/api/machines/machinetype/4242/',
|
"/api/machines/machinetype/4242/",
|
||||||
'/api/machines/mx/4242/',
|
"/api/machines/mx/4242/",
|
||||||
'/api/machines/nas/4242/',
|
"/api/machines/nas/4242/",
|
||||||
'/api/machines/ns/4242/',
|
"/api/machines/ns/4242/",
|
||||||
'/api/machines/ouvertureportlist/4242/',
|
"/api/machines/ouvertureportlist/4242/",
|
||||||
'/api/machines/ouvertureport/4242/',
|
"/api/machines/ouvertureport/4242/",
|
||||||
'/api/machines/servicelink/4242/',
|
"/api/machines/servicelink/4242/",
|
||||||
'/api/machines/service/4242/',
|
"/api/machines/service/4242/",
|
||||||
'/api/machines/soa/4242/',
|
"/api/machines/soa/4242/",
|
||||||
'/api/machines/srv/4242/',
|
"/api/machines/srv/4242/",
|
||||||
'/api/machines/txt/4242/',
|
"/api/machines/txt/4242/",
|
||||||
'/api/machines/vlan/4242/',
|
"/api/machines/vlan/4242/",
|
||||||
'/api/preferences/service/4242/',
|
"/api/preferences/service/4242/",
|
||||||
'/api/topologie/acesspoint/4242/',
|
"/api/topologie/acesspoint/4242/",
|
||||||
'/api/topologie/building/4242/',
|
"/api/topologie/building/4242/",
|
||||||
'/api/topologie/constructorswitch/4242/',
|
"/api/topologie/constructorswitch/4242/",
|
||||||
'/api/topologie/modelswitch/4242/',
|
"/api/topologie/modelswitch/4242/",
|
||||||
'/api/topologie/room/4242/',
|
"/api/topologie/room/4242/",
|
||||||
'/api/topologie/server/4242/',
|
"/api/topologie/server/4242/",
|
||||||
'/api/topologie/stack/4242/',
|
"/api/topologie/stack/4242/",
|
||||||
'/api/topologie/switch/4242/',
|
"/api/topologie/switch/4242/",
|
||||||
'/api/topologie/switchbay/4242/',
|
"/api/topologie/switchbay/4242/",
|
||||||
'/api/topologie/switchport/4242/',
|
"/api/topologie/switchport/4242/",
|
||||||
'/api/users/adherent/4242/',
|
"/api/users/adherent/4242/",
|
||||||
'/api/users/ban/4242/',
|
"/api/users/ban/4242/",
|
||||||
'/api/users/club/4242/',
|
"/api/users/club/4242/",
|
||||||
'/api/users/listright/4242/',
|
"/api/users/listright/4242/",
|
||||||
'/api/users/school/4242/',
|
"/api/users/school/4242/",
|
||||||
'/api/users/serviceuser/4242/',
|
"/api/users/serviceuser/4242/",
|
||||||
'/api/users/shell/4242/',
|
"/api/users/shell/4242/",
|
||||||
'/api/users/user/4242/',
|
"/api/users/user/4242/",
|
||||||
'/api/users/whitelist/4242/',
|
"/api/users/whitelist/4242/",
|
||||||
]
|
]
|
||||||
|
|
||||||
stduser = None
|
stduser = None
|
||||||
|
@ -232,26 +231,18 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
|
|
||||||
# A user with no rights
|
# A user with no rights
|
||||||
cls.stduser = users.User.objects.create_user(
|
cls.stduser = users.User.objects.create_user(
|
||||||
"apistduser",
|
"apistduser", "apistduser", "apistduser@example.net", "apistduser"
|
||||||
"apistduser",
|
|
||||||
"apistduser@example.net",
|
|
||||||
"apistduser"
|
|
||||||
)
|
)
|
||||||
# A user with all the rights
|
# A user with all the rights
|
||||||
cls.superuser = users.User.objects.create_superuser(
|
cls.superuser = users.User.objects.create_superuser(
|
||||||
"apisuperuser",
|
"apisuperuser", "apisuperuser", "apisuperuser@example.net", "apisuperuser"
|
||||||
"apisuperuser",
|
|
||||||
"apisuperuser@example.net",
|
|
||||||
"apisuperuser"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Creates 1 instance for each object so the "details" endpoints
|
# Creates 1 instance for each object so the "details" endpoints
|
||||||
# can be tested too. Objects need to be created in the right order.
|
# can be tested too. Objects need to be created in the right order.
|
||||||
# Dependencies (relatedFields, ...) are highlighted by a comment at
|
# Dependencies (relatedFields, ...) are highlighted by a comment at
|
||||||
# the end of the concerned line (# Dep <model>).
|
# the end of the concerned line (# Dep <model>).
|
||||||
cls.users_school_1 = users.School.objects.create(
|
cls.users_school_1 = users.School.objects.create(name="users_school_1")
|
||||||
name="users_school_1"
|
|
||||||
)
|
|
||||||
cls.users_school_1.save()
|
cls.users_school_1.save()
|
||||||
cls.users_listshell_1 = users.ListShell.objects.create(
|
cls.users_listshell_1 = users.ListShell.objects.create(
|
||||||
shell="users_listshell_1"
|
shell="users_listshell_1"
|
||||||
|
@ -270,7 +261,7 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
registered=datetime.datetime.now(datetime.timezone.utc),
|
registered=datetime.datetime.now(datetime.timezone.utc),
|
||||||
telephone="0123456789",
|
telephone="0123456789",
|
||||||
uid_number=21102,
|
uid_number=21102,
|
||||||
rezo_rez_uid=21102
|
rezo_rez_uid=21102,
|
||||||
)
|
)
|
||||||
cls.users_user_1 = cls.users_adherent_1
|
cls.users_user_1 = cls.users_adherent_1
|
||||||
cls.cotisations_article_1 = cotisations.Article.objects.create(
|
cls.cotisations_article_1 = cotisations.Article.objects.create(
|
||||||
|
@ -278,14 +269,14 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
prix=10,
|
prix=10,
|
||||||
duration=1,
|
duration=1,
|
||||||
type_user=cotisations.Article.USER_TYPES[0][0],
|
type_user=cotisations.Article.USER_TYPES[0][0],
|
||||||
type_cotisation=cotisations.Article.COTISATION_TYPE[0][0]
|
type_cotisation=cotisations.Article.COTISATION_TYPE[0][0],
|
||||||
)
|
)
|
||||||
cls.cotisations_banque_1 = cotisations.Banque.objects.create(
|
cls.cotisations_banque_1 = cotisations.Banque.objects.create(
|
||||||
name="cotisations_banque_1"
|
name="cotisations_banque_1"
|
||||||
)
|
)
|
||||||
cls.cotisations_paiement_1 = cotisations.Paiement.objects.create(
|
cls.cotisations_paiement_1 = cotisations.Paiement.objects.create(
|
||||||
moyen="cotisations_paiement_1",
|
moyen="cotisations_paiement_1",
|
||||||
type_paiement=cotisations.Paiement.PAYMENT_TYPES[0][0]
|
type_paiement=cotisations.Paiement.PAYMENT_TYPES[0][0],
|
||||||
)
|
)
|
||||||
cls.cotisations_facture_1 = cotisations.Facture.objects.create(
|
cls.cotisations_facture_1 = cotisations.Facture.objects.create(
|
||||||
user=cls.users_user_1, # Dep users.User
|
user=cls.users_user_1, # Dep users.User
|
||||||
|
@ -294,7 +285,7 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
cheque="1234567890",
|
cheque="1234567890",
|
||||||
date=datetime.datetime.now(datetime.timezone.utc),
|
date=datetime.datetime.now(datetime.timezone.utc),
|
||||||
valid=True,
|
valid=True,
|
||||||
control=False
|
control=False,
|
||||||
)
|
)
|
||||||
cls.cotisations_vente_1 = cotisations.Vente.objects.create(
|
cls.cotisations_vente_1 = cotisations.Vente.objects.create(
|
||||||
facture=cls.cotisations_facture_1, # Dep cotisations.Facture
|
facture=cls.cotisations_facture_1, # Dep cotisations.Facture
|
||||||
|
@ -302,18 +293,18 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
name="cotisations_vente_1",
|
name="cotisations_vente_1",
|
||||||
prix=10,
|
prix=10,
|
||||||
duration=1,
|
duration=1,
|
||||||
type_cotisation=cotisations.Vente.COTISATION_TYPE[0][0]
|
type_cotisation=cotisations.Vente.COTISATION_TYPE[0][0],
|
||||||
)
|
)
|
||||||
# A cotisation is automatically created by the Vente object and
|
# A cotisation is automatically created by the Vente object and
|
||||||
# trying to create another cotisation associated with this vente
|
# trying to create another cotisation associated with this vente
|
||||||
# will fail so we simply retrieve it so it can be used in the tests
|
# will fail so we simply retrieve it so it can be used in the tests
|
||||||
cls.cotisations_cotisation_1 = cotisations.Cotisation.objects.get(
|
cls.cotisations_cotisation_1 = cotisations.Cotisation.objects.get(
|
||||||
vente=cls.cotisations_vente_1, # Dep cotisations.Vente
|
vente=cls.cotisations_vente_1 # Dep cotisations.Vente
|
||||||
)
|
)
|
||||||
cls.machines_machine_1 = machines.Machine.objects.create(
|
cls.machines_machine_1 = machines.Machine.objects.create(
|
||||||
user=cls.users_user_1, # Dep users.User
|
user=cls.users_user_1, # Dep users.User
|
||||||
name="machines_machine_1",
|
name="machines_machine_1",
|
||||||
active=True
|
active=True,
|
||||||
)
|
)
|
||||||
cls.machines_ouvertureportlist_1 = machines.OuverturePortList.objects.create(
|
cls.machines_ouvertureportlist_1 = machines.OuverturePortList.objects.create(
|
||||||
name="machines_ouvertureportlist_1"
|
name="machines_ouvertureportlist_1"
|
||||||
|
@ -324,19 +315,17 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
refresh=86400,
|
refresh=86400,
|
||||||
retry=7200,
|
retry=7200,
|
||||||
expire=3600000,
|
expire=3600000,
|
||||||
ttl=172800
|
ttl=172800,
|
||||||
)
|
)
|
||||||
cls.machines_extension_1 = machines.Extension.objects.create(
|
cls.machines_extension_1 = machines.Extension.objects.create(
|
||||||
name="machines_extension_1",
|
name="machines_extension_1",
|
||||||
need_infra=False,
|
need_infra=False,
|
||||||
# Do not set origin because of circular dependency
|
# Do not set origin because of circular dependency
|
||||||
origin_v6="2001:db8:1234::",
|
origin_v6="2001:db8:1234::",
|
||||||
soa=cls.machines_soa_1 # Dep machines.SOA
|
soa=cls.machines_soa_1, # Dep machines.SOA
|
||||||
)
|
)
|
||||||
cls.machines_vlan_1 = machines.Vlan.objects.create(
|
cls.machines_vlan_1 = machines.Vlan.objects.create(
|
||||||
vlan_id=0,
|
vlan_id=0, name="machines_vlan_1", comment="machines Vlan 1"
|
||||||
name="machines_vlan_1",
|
|
||||||
comment="machines Vlan 1"
|
|
||||||
)
|
)
|
||||||
cls.machines_iptype_1 = machines.IpType.objects.create(
|
cls.machines_iptype_1 = machines.IpType.objects.create(
|
||||||
type="machines_iptype_1",
|
type="machines_iptype_1",
|
||||||
|
@ -346,13 +335,12 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
domaine_ip_stop="10.0.0.255",
|
domaine_ip_stop="10.0.0.255",
|
||||||
prefix_v6="2001:db8:1234::",
|
prefix_v6="2001:db8:1234::",
|
||||||
vlan=cls.machines_vlan_1, # Dep machines.Vlan
|
vlan=cls.machines_vlan_1, # Dep machines.Vlan
|
||||||
ouverture_ports=cls.machines_ouvertureportlist_1 # Dep machines.OuverturePortList
|
ouverture_ports=cls.machines_ouvertureportlist_1, # Dep machines.OuverturePortList
|
||||||
)
|
)
|
||||||
# All IPs in the IpType range are autocreated so we can't create
|
# All IPs in the IpType range are autocreated so we can't create
|
||||||
# new ones and thus we only retrieve it if needed in the tests
|
# new ones and thus we only retrieve it if needed in the tests
|
||||||
cls.machines_iplist_1 = machines.IpList.objects.get(
|
cls.machines_iplist_1 = machines.IpList.objects.get(
|
||||||
ipv4="10.0.0.1",
|
ipv4="10.0.0.1", ip_type=cls.machines_iptype_1 # Dep machines.IpType
|
||||||
ip_type=cls.machines_iptype_1, # Dep machines.IpType
|
|
||||||
)
|
)
|
||||||
cls.machines_machinetype_1 = machines.MachineType.objects.create(
|
cls.machines_machinetype_1 = machines.MachineType.objects.create(
|
||||||
type="machines_machinetype_1",
|
type="machines_machinetype_1",
|
||||||
|
@ -375,16 +363,16 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
cls.machines_mx_1 = machines.Mx.objects.create(
|
cls.machines_mx_1 = machines.Mx.objects.create(
|
||||||
zone=cls.machines_extension_1, # Dep machines.Extension
|
zone=cls.machines_extension_1, # Dep machines.Extension
|
||||||
priority=10,
|
priority=10,
|
||||||
name=cls.machines_domain_1 # Dep machines.Domain
|
name=cls.machines_domain_1, # Dep machines.Domain
|
||||||
)
|
)
|
||||||
cls.machines_ns_1 = machines.Ns.objects.create(
|
cls.machines_ns_1 = machines.Ns.objects.create(
|
||||||
zone=cls.machines_extension_1, # Dep machines.Extension
|
zone=cls.machines_extension_1, # Dep machines.Extension
|
||||||
ns=cls.machines_domain_1 # Dep machines.Domain
|
ns=cls.machines_domain_1, # Dep machines.Domain
|
||||||
)
|
)
|
||||||
cls.machines_txt_1 = machines.Txt.objects.create(
|
cls.machines_txt_1 = machines.Txt.objects.create(
|
||||||
zone=cls.machines_extension_1, # Dep machines.Extension
|
zone=cls.machines_extension_1, # Dep machines.Extension
|
||||||
field1="machines_txt_1",
|
field1="machines_txt_1",
|
||||||
field2="machies Txt 1"
|
field2="machies Txt 1",
|
||||||
)
|
)
|
||||||
cls.machines_srv_1 = machines.Srv.objects.create(
|
cls.machines_srv_1 = machines.Srv.objects.create(
|
||||||
service="machines_srv_1",
|
service="machines_srv_1",
|
||||||
|
@ -398,7 +386,7 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
cls.machines_ipv6list_1 = machines.Ipv6List.objects.create(
|
cls.machines_ipv6list_1 = machines.Ipv6List.objects.create(
|
||||||
ipv6="2001:db8:1234::",
|
ipv6="2001:db8:1234::",
|
||||||
interface=cls.machines_interface_1, # Dep machines.Interface
|
interface=cls.machines_interface_1, # Dep machines.Interface
|
||||||
slaac_ip=False
|
slaac_ip=False,
|
||||||
)
|
)
|
||||||
cls.machines_service_1 = machines.Service.objects.create(
|
cls.machines_service_1 = machines.Service.objects.create(
|
||||||
service_type="machines_service_1",
|
service_type="machines_service_1",
|
||||||
|
@ -410,45 +398,45 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
service=cls.machines_service_1, # Dep machines.Service
|
service=cls.machines_service_1, # Dep machines.Service
|
||||||
server=cls.machines_interface_1, # Dep machines.Interface
|
server=cls.machines_interface_1, # Dep machines.Interface
|
||||||
last_regen=datetime.datetime.now(datetime.timezone.utc),
|
last_regen=datetime.datetime.now(datetime.timezone.utc),
|
||||||
asked_regen=False
|
asked_regen=False,
|
||||||
)
|
)
|
||||||
cls.machines_ouvertureport_1 = machines.OuverturePort.objects.create(
|
cls.machines_ouvertureport_1 = machines.OuverturePort.objects.create(
|
||||||
begin=1,
|
begin=1,
|
||||||
end=2,
|
end=2,
|
||||||
port_list=cls.machines_ouvertureportlist_1, # Dep machines.OuverturePortList
|
port_list=cls.machines_ouvertureportlist_1, # Dep machines.OuverturePortList
|
||||||
protocole=machines.OuverturePort.TCP,
|
protocole=machines.OuverturePort.TCP,
|
||||||
io=machines.OuverturePort.OUT
|
io=machines.OuverturePort.OUT,
|
||||||
)
|
)
|
||||||
cls.machines_nas_1 = machines.Nas.objects.create(
|
cls.machines_nas_1 = machines.Nas.objects.create(
|
||||||
name="machines_nas_1",
|
name="machines_nas_1",
|
||||||
nas_type=cls.machines_machinetype_1, # Dep machines.MachineType
|
nas_type=cls.machines_machinetype_1, # Dep machines.MachineType
|
||||||
machine_type=cls.machines_machinetype_1, # Dep machines.MachineType
|
machine_type=cls.machines_machinetype_1, # Dep machines.MachineType
|
||||||
port_access_mode=machines.Nas.AUTH[0][0],
|
port_access_mode=machines.Nas.AUTH[0][0],
|
||||||
autocapture_mac=False
|
autocapture_mac=False,
|
||||||
)
|
)
|
||||||
cls.preferences_service_1 = preferences.Service.objects.create(
|
cls.preferences_service_1 = preferences.Service.objects.create(
|
||||||
name="preferences_service_1",
|
name="preferences_service_1",
|
||||||
url="https://example.net",
|
url="https://example.net",
|
||||||
description="preferences Service 1",
|
description="preferences Service 1",
|
||||||
image="/media/logo/none.png"
|
image="/media/logo/none.png",
|
||||||
)
|
)
|
||||||
cls.topologie_stack_1 = topologie.Stack.objects.create(
|
cls.topologie_stack_1 = topologie.Stack.objects.create(
|
||||||
name="topologie_stack_1",
|
name="topologie_stack_1",
|
||||||
stack_id="1",
|
stack_id="1",
|
||||||
details="topologie Stack 1",
|
details="topologie Stack 1",
|
||||||
member_id_min=1,
|
member_id_min=1,
|
||||||
member_id_max=10
|
member_id_max=10,
|
||||||
)
|
)
|
||||||
cls.topologie_accespoint_1 = topologie.AccessPoint.objects.create(
|
cls.topologie_accespoint_1 = topologie.AccessPoint.objects.create(
|
||||||
user=cls.users_user_1, # Dep users.User
|
user=cls.users_user_1, # Dep users.User
|
||||||
name="machines_machine_1",
|
name="machines_machine_1",
|
||||||
active=True,
|
active=True,
|
||||||
location="topologie AccessPoint 1"
|
location="topologie AccessPoint 1",
|
||||||
)
|
)
|
||||||
cls.topologie_server_1 = topologie.Server.objects.create(
|
cls.topologie_server_1 = topologie.Server.objects.create(
|
||||||
user=cls.users_user_1, # Dep users.User
|
user=cls.users_user_1, # Dep users.User
|
||||||
name="machines_machine_1",
|
name="machines_machine_1",
|
||||||
active=True
|
active=True,
|
||||||
)
|
)
|
||||||
cls.topologie_building_1 = topologie.Building.objects.create(
|
cls.topologie_building_1 = topologie.Building.objects.create(
|
||||||
name="topologie_building_1"
|
name="topologie_building_1"
|
||||||
|
@ -456,14 +444,14 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
cls.topologie_switchbay_1 = topologie.SwitchBay.objects.create(
|
cls.topologie_switchbay_1 = topologie.SwitchBay.objects.create(
|
||||||
name="topologie_switchbay_1",
|
name="topologie_switchbay_1",
|
||||||
building=cls.topologie_building_1, # Dep topologie.Building
|
building=cls.topologie_building_1, # Dep topologie.Building
|
||||||
info="topologie SwitchBay 1"
|
info="topologie SwitchBay 1",
|
||||||
)
|
)
|
||||||
cls.topologie_constructorswitch_1 = topologie.ConstructorSwitch.objects.create(
|
cls.topologie_constructorswitch_1 = topologie.ConstructorSwitch.objects.create(
|
||||||
name="topologie_constructorswitch_1"
|
name="topologie_constructorswitch_1"
|
||||||
)
|
)
|
||||||
cls.topologie_modelswitch_1 = topologie.ModelSwitch.objects.create(
|
cls.topologie_modelswitch_1 = topologie.ModelSwitch.objects.create(
|
||||||
reference="topologie_modelswitch_1",
|
reference="topologie_modelswitch_1",
|
||||||
constructor=cls.topologie_constructorswitch_1 # Dep topologie.ConstructorSwitch
|
constructor=cls.topologie_constructorswitch_1, # Dep topologie.ConstructorSwitch
|
||||||
)
|
)
|
||||||
cls.topologie_switch_1 = topologie.Switch.objects.create(
|
cls.topologie_switch_1 = topologie.Switch.objects.create(
|
||||||
user=cls.users_user_1, # Dep users.User
|
user=cls.users_user_1, # Dep users.User
|
||||||
|
@ -473,11 +461,10 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
stack=cls.topologie_stack_1, # Dep topologie.Stack
|
stack=cls.topologie_stack_1, # Dep topologie.Stack
|
||||||
stack_member_id=1,
|
stack_member_id=1,
|
||||||
model=cls.topologie_modelswitch_1, # Dep topologie.ModelSwitch
|
model=cls.topologie_modelswitch_1, # Dep topologie.ModelSwitch
|
||||||
switchbay=cls.topologie_switchbay_1 # Dep topologie.SwitchBay
|
switchbay=cls.topologie_switchbay_1, # Dep topologie.SwitchBay
|
||||||
)
|
)
|
||||||
cls.topologie_room_1 = topologie.Room.objects.create(
|
cls.topologie_room_1 = topologie.Room.objects.create(
|
||||||
name="topologie_romm_1",
|
name="topologie_romm_1", details="topologie Room 1"
|
||||||
details="topologie Room 1"
|
|
||||||
)
|
)
|
||||||
cls.topologie_port_1 = topologie.Port.objects.create(
|
cls.topologie_port_1 = topologie.Port.objects.create(
|
||||||
switch=cls.topologie_switch_1, # Dep topologie.Switch
|
switch=cls.topologie_switch_1, # Dep topologie.Switch
|
||||||
|
@ -485,7 +472,7 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
room=cls.topologie_room_1, # Dep topologie.Room
|
room=cls.topologie_room_1, # Dep topologie.Room
|
||||||
radius=topologie.Port.STATES[0][0],
|
radius=topologie.Port.STATES[0][0],
|
||||||
vlan_force=cls.machines_vlan_1, # Dep machines.Vlan
|
vlan_force=cls.machines_vlan_1, # Dep machines.Vlan
|
||||||
details="topologie_switch_1"
|
details="topologie_switch_1",
|
||||||
)
|
)
|
||||||
cls.topologie_port_2 = topologie.Port.objects.create(
|
cls.topologie_port_2 = topologie.Port.objects.create(
|
||||||
switch=cls.topologie_switch_1, # Dep topologie.Switch
|
switch=cls.topologie_switch_1, # Dep topologie.Switch
|
||||||
|
@ -493,7 +480,7 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
machine_interface=cls.machines_interface_1, # Dep machines.Interface
|
machine_interface=cls.machines_interface_1, # Dep machines.Interface
|
||||||
radius=topologie.Port.STATES[0][0],
|
radius=topologie.Port.STATES[0][0],
|
||||||
vlan_force=cls.machines_vlan_1, # Dep machines.Vlan
|
vlan_force=cls.machines_vlan_1, # Dep machines.Vlan
|
||||||
details="topologie_switch_1"
|
details="topologie_switch_1",
|
||||||
)
|
)
|
||||||
cls.topologie_port_3 = topologie.Port.objects.create(
|
cls.topologie_port_3 = topologie.Port.objects.create(
|
||||||
switch=cls.topologie_switch_1, # Dep topologie.Switch
|
switch=cls.topologie_switch_1, # Dep topologie.Switch
|
||||||
|
@ -501,14 +488,15 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
room=cls.topologie_room_1, # Dep topologie.Room
|
room=cls.topologie_room_1, # Dep topologie.Room
|
||||||
radius=topologie.Port.STATES[0][0],
|
radius=topologie.Port.STATES[0][0],
|
||||||
# Do not defines related because circular dependency # Dep machines.Vlan
|
# Do not defines related because circular dependency # Dep machines.Vlan
|
||||||
details="topologie_switch_1"
|
details="topologie_switch_1",
|
||||||
)
|
)
|
||||||
cls.users_ban_1 = users.Ban.objects.create(
|
cls.users_ban_1 = users.Ban.objects.create(
|
||||||
user=cls.users_user_1, # Dep users.User
|
user=cls.users_user_1, # Dep users.User
|
||||||
raison="users Ban 1",
|
raison="users Ban 1",
|
||||||
date_start=datetime.datetime.now(datetime.timezone.utc),
|
date_start=datetime.datetime.now(datetime.timezone.utc),
|
||||||
date_end=datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(days=1),
|
date_end=datetime.datetime.now(datetime.timezone.utc)
|
||||||
state=users.Ban.STATES[0][0]
|
+ datetime.timedelta(days=1),
|
||||||
|
state=users.Ban.STATES[0][0],
|
||||||
)
|
)
|
||||||
cls.users_club_1 = users.Club.objects.create(
|
cls.users_club_1 = users.Club.objects.create(
|
||||||
password="password",
|
password="password",
|
||||||
|
@ -524,7 +512,7 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
registered=datetime.datetime.now(datetime.timezone.utc),
|
registered=datetime.datetime.now(datetime.timezone.utc),
|
||||||
telephone="0123456789",
|
telephone="0123456789",
|
||||||
uid_number=21103,
|
uid_number=21103,
|
||||||
rezo_rez_uid=21103
|
rezo_rez_uid=21103,
|
||||||
)
|
)
|
||||||
# Need merge of MR145 to work
|
# Need merge of MR145 to work
|
||||||
# TODO: Merge !145
|
# TODO: Merge !145
|
||||||
|
@ -539,17 +527,17 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
last_login=datetime.datetime.now(datetime.timezone.utc),
|
last_login=datetime.datetime.now(datetime.timezone.utc),
|
||||||
pseudo="usersserviceuser1",
|
pseudo="usersserviceuser1",
|
||||||
access_group=users.ServiceUser.ACCESS[0][0],
|
access_group=users.ServiceUser.ACCESS[0][0],
|
||||||
comment="users ServiceUser 1"
|
comment="users ServiceUser 1",
|
||||||
)
|
)
|
||||||
cls.users_whitelist_1 = users.Whitelist.objects.create(
|
cls.users_whitelist_1 = users.Whitelist.objects.create(
|
||||||
user=cls.users_user_1,
|
user=cls.users_user_1,
|
||||||
raison="users Whitelist 1",
|
raison="users Whitelist 1",
|
||||||
date_start=datetime.datetime.now(datetime.timezone.utc),
|
date_start=datetime.datetime.now(datetime.timezone.utc),
|
||||||
date_end=datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(days=1)
|
date_end=datetime.datetime.now(datetime.timezone.utc)
|
||||||
|
+ datetime.timedelta(days=1),
|
||||||
)
|
)
|
||||||
|
|
||||||
def check_responses_code(self, urls, expected_code, formats=None,
|
def check_responses_code(self, urls, expected_code, formats=None, assert_more=None):
|
||||||
assert_more=None):
|
|
||||||
"""Utility function to test if a list of urls answer an expected code.
|
"""Utility function to test if a list of urls answer an expected code.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -665,17 +653,20 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
"""
|
"""
|
||||||
self.client.force_authenticate(user=self.superuser)
|
self.client.force_authenticate(user=self.superuser)
|
||||||
|
|
||||||
urls = self.no_auth_endpoints + self.auth_no_perm_endpoints + \
|
urls = (
|
||||||
self.auth_perm_endpoints
|
self.no_auth_endpoints
|
||||||
|
+ self.auth_no_perm_endpoints
|
||||||
|
+ self.auth_perm_endpoints
|
||||||
|
)
|
||||||
|
|
||||||
def assert_more(response, url, format):
|
def assert_more(response, url, format):
|
||||||
"""Assert the response is valid json when format is json"""
|
"""Assert the response is valid json when format is json"""
|
||||||
if format is 'json':
|
if format is "json":
|
||||||
json.loads(response.content.decode())
|
json.loads(response.content.decode())
|
||||||
|
|
||||||
self.check_responses_code(urls, codes.ok,
|
self.check_responses_code(
|
||||||
formats=[None, 'json', 'api'],
|
urls, codes.ok, formats=[None, "json", "api"], assert_more=assert_more
|
||||||
assert_more=assert_more)
|
)
|
||||||
|
|
||||||
|
|
||||||
class APIPaginationTestCase(APITestCase):
|
class APIPaginationTestCase(APITestCase):
|
||||||
|
@ -688,56 +679,56 @@ class APIPaginationTestCase(APITestCase):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
endpoints = [
|
endpoints = [
|
||||||
'/api/cotisations/article/',
|
"/api/cotisations/article/",
|
||||||
'/api/cotisations/banque/',
|
"/api/cotisations/banque/",
|
||||||
'/api/cotisations/cotisation/',
|
"/api/cotisations/cotisation/",
|
||||||
'/api/cotisations/facture/',
|
"/api/cotisations/facture/",
|
||||||
'/api/cotisations/paiement/',
|
"/api/cotisations/paiement/",
|
||||||
'/api/cotisations/vente/',
|
"/api/cotisations/vente/",
|
||||||
'/api/machines/domain/',
|
"/api/machines/domain/",
|
||||||
'/api/machines/extension/',
|
"/api/machines/extension/",
|
||||||
'/api/machines/interface/',
|
"/api/machines/interface/",
|
||||||
'/api/machines/iplist/',
|
"/api/machines/iplist/",
|
||||||
'/api/machines/iptype/',
|
"/api/machines/iptype/",
|
||||||
'/api/machines/ipv6list/',
|
"/api/machines/ipv6list/",
|
||||||
'/api/machines/machine/',
|
"/api/machines/machine/",
|
||||||
'/api/machines/machinetype/',
|
"/api/machines/machinetype/",
|
||||||
'/api/machines/mx/',
|
"/api/machines/mx/",
|
||||||
'/api/machines/nas/',
|
"/api/machines/nas/",
|
||||||
'/api/machines/ns/',
|
"/api/machines/ns/",
|
||||||
'/api/machines/ouvertureportlist/',
|
"/api/machines/ouvertureportlist/",
|
||||||
'/api/machines/ouvertureport/',
|
"/api/machines/ouvertureport/",
|
||||||
'/api/machines/servicelink/',
|
"/api/machines/servicelink/",
|
||||||
'/api/machines/service/',
|
"/api/machines/service/",
|
||||||
'/api/machines/soa/',
|
"/api/machines/soa/",
|
||||||
'/api/machines/srv/',
|
"/api/machines/srv/",
|
||||||
'/api/machines/txt/',
|
"/api/machines/txt/",
|
||||||
'/api/machines/vlan/',
|
"/api/machines/vlan/",
|
||||||
'/api/preferences/service/',
|
"/api/preferences/service/",
|
||||||
'/api/topologie/acesspoint/',
|
"/api/topologie/acesspoint/",
|
||||||
'/api/topologie/building/',
|
"/api/topologie/building/",
|
||||||
'/api/topologie/constructorswitch/',
|
"/api/topologie/constructorswitch/",
|
||||||
'/api/topologie/modelswitch/',
|
"/api/topologie/modelswitch/",
|
||||||
'/api/topologie/room/',
|
"/api/topologie/room/",
|
||||||
'/api/topologie/server/',
|
"/api/topologie/server/",
|
||||||
'/api/topologie/stack/',
|
"/api/topologie/stack/",
|
||||||
'/api/topologie/switch/',
|
"/api/topologie/switch/",
|
||||||
'/api/topologie/switchbay/',
|
"/api/topologie/switchbay/",
|
||||||
'/api/topologie/switchport/',
|
"/api/topologie/switchport/",
|
||||||
'/api/users/adherent/',
|
"/api/users/adherent/",
|
||||||
'/api/users/ban/',
|
"/api/users/ban/",
|
||||||
'/api/users/club/',
|
"/api/users/club/",
|
||||||
'/api/users/listright/',
|
"/api/users/listright/",
|
||||||
'/api/users/school/',
|
"/api/users/school/",
|
||||||
'/api/users/serviceuser/',
|
"/api/users/serviceuser/",
|
||||||
'/api/users/shell/',
|
"/api/users/shell/",
|
||||||
'/api/users/user/',
|
"/api/users/user/",
|
||||||
'/api/users/whitelist/',
|
"/api/users/whitelist/",
|
||||||
'/api/dns/zones/',
|
"/api/dns/zones/",
|
||||||
'/api/dhcp/hostmacip/',
|
"/api/dhcp/hostmacip/",
|
||||||
'/api/mailing/standard',
|
"/api/mailing/standard",
|
||||||
'/api/mailing/club',
|
"/api/mailing/club",
|
||||||
'/api/services/regen/',
|
"/api/services/regen/",
|
||||||
]
|
]
|
||||||
superuser = None
|
superuser = None
|
||||||
|
|
||||||
|
@ -752,7 +743,7 @@ class APIPaginationTestCase(APITestCase):
|
||||||
"apisuperuser2",
|
"apisuperuser2",
|
||||||
"apisuperuser2",
|
"apisuperuser2",
|
||||||
"apisuperuser2@example.net",
|
"apisuperuser2@example.net",
|
||||||
"apisuperuser2"
|
"apisuperuser2",
|
||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -771,10 +762,10 @@ class APIPaginationTestCase(APITestCase):
|
||||||
self.client.force_authenticate(self.superuser)
|
self.client.force_authenticate(self.superuser)
|
||||||
for url in self.endpoints:
|
for url in self.endpoints:
|
||||||
with self.subTest(url=url):
|
with self.subTest(url=url):
|
||||||
response = self.client.get(url, format='json')
|
response = self.client.get(url, format="json")
|
||||||
res_json = json.loads(response.content.decode())
|
res_json = json.loads(response.content.decode())
|
||||||
assert 'count' in res_json.keys()
|
assert "count" in res_json.keys()
|
||||||
assert 'next' in res_json.keys()
|
assert "next" in res_json.keys()
|
||||||
assert 'previous' in res_json.keys()
|
assert "previous" in res_json.keys()
|
||||||
assert 'results' in res_json.keys()
|
assert "results" in res_json.keys()
|
||||||
assert not len('results') > 100
|
assert not len("results") > 100
|
||||||
|
|
170
api/urls.py
170
api/urls.py
|
@ -34,95 +34,109 @@ from .routers import AllViewsRouter
|
||||||
|
|
||||||
router = AllViewsRouter()
|
router = AllViewsRouter()
|
||||||
# COTISATIONS
|
# COTISATIONS
|
||||||
router.register_viewset(r'cotisations/facture', views.FactureViewSet)
|
router.register_viewset(r"cotisations/facture", views.FactureViewSet)
|
||||||
router.register_viewset(r'cotisations/vente', views.VenteViewSet)
|
router.register_viewset(r"cotisations/vente", views.VenteViewSet)
|
||||||
router.register_viewset(r'cotisations/article', views.ArticleViewSet)
|
router.register_viewset(r"cotisations/article", views.ArticleViewSet)
|
||||||
router.register_viewset(r'cotisations/banque', views.BanqueViewSet)
|
router.register_viewset(r"cotisations/banque", views.BanqueViewSet)
|
||||||
router.register_viewset(r'cotisations/paiement', views.PaiementViewSet)
|
router.register_viewset(r"cotisations/paiement", views.PaiementViewSet)
|
||||||
router.register_viewset(r'cotisations/cotisation', views.CotisationViewSet)
|
router.register_viewset(r"cotisations/cotisation", views.CotisationViewSet)
|
||||||
# MACHINES
|
# MACHINES
|
||||||
router.register_viewset(r'machines/machine', views.MachineViewSet)
|
router.register_viewset(r"machines/machine", views.MachineViewSet)
|
||||||
router.register_viewset(r'machines/machinetype', views.MachineTypeViewSet)
|
router.register_viewset(r"machines/machinetype", views.MachineTypeViewSet)
|
||||||
router.register_viewset(r'machines/iptype', views.IpTypeViewSet)
|
router.register_viewset(r"machines/iptype", views.IpTypeViewSet)
|
||||||
router.register_viewset(r'machines/vlan', views.VlanViewSet)
|
router.register_viewset(r"machines/vlan", views.VlanViewSet)
|
||||||
router.register_viewset(r'machines/nas', views.NasViewSet)
|
router.register_viewset(r"machines/nas", views.NasViewSet)
|
||||||
router.register_viewset(r'machines/soa', views.SOAViewSet)
|
router.register_viewset(r"machines/soa", views.SOAViewSet)
|
||||||
router.register_viewset(r'machines/extension', views.ExtensionViewSet)
|
router.register_viewset(r"machines/extension", views.ExtensionViewSet)
|
||||||
router.register_viewset(r'machines/mx', views.MxViewSet)
|
router.register_viewset(r"machines/mx", views.MxViewSet)
|
||||||
router.register_viewset(r'machines/ns', views.NsViewSet)
|
router.register_viewset(r"machines/ns", views.NsViewSet)
|
||||||
router.register_viewset(r'machines/txt', views.TxtViewSet)
|
router.register_viewset(r"machines/txt", views.TxtViewSet)
|
||||||
router.register_viewset(r'machines/dname', views.DNameViewSet)
|
router.register_viewset(r"machines/dname", views.DNameViewSet)
|
||||||
router.register_viewset(r'machines/srv', views.SrvViewSet)
|
router.register_viewset(r"machines/srv", views.SrvViewSet)
|
||||||
router.register_viewset(r'machines/sshfp', views.SshFpViewSet)
|
router.register_viewset(r"machines/sshfp", views.SshFpViewSet)
|
||||||
router.register_viewset(r'machines/interface', views.InterfaceViewSet)
|
router.register_viewset(r"machines/interface", views.InterfaceViewSet)
|
||||||
router.register_viewset(r'machines/ipv6list', views.Ipv6ListViewSet)
|
router.register_viewset(r"machines/ipv6list", views.Ipv6ListViewSet)
|
||||||
router.register_viewset(r'machines/domain', views.DomainViewSet)
|
router.register_viewset(r"machines/domain", views.DomainViewSet)
|
||||||
router.register_viewset(r'machines/iplist', views.IpListViewSet)
|
router.register_viewset(r"machines/iplist", views.IpListViewSet)
|
||||||
router.register_viewset(r'machines/service', views.ServiceViewSet)
|
router.register_viewset(r"machines/service", views.ServiceViewSet)
|
||||||
router.register_viewset(r'machines/servicelink', views.ServiceLinkViewSet, base_name='servicelink')
|
router.register_viewset(
|
||||||
router.register_viewset(r'machines/ouvertureportlist', views.OuverturePortListViewSet)
|
r"machines/servicelink", views.ServiceLinkViewSet, base_name="servicelink"
|
||||||
router.register_viewset(r'machines/ouvertureport', views.OuverturePortViewSet)
|
)
|
||||||
router.register_viewset(r'machines/role', views.RoleViewSet)
|
router.register_viewset(r"machines/ouvertureportlist", views.OuverturePortListViewSet)
|
||||||
|
router.register_viewset(r"machines/ouvertureport", views.OuverturePortViewSet)
|
||||||
|
router.register_viewset(r"machines/role", views.RoleViewSet)
|
||||||
# PREFERENCES
|
# PREFERENCES
|
||||||
router.register_view(r'preferences/optionaluser', views.OptionalUserView),
|
router.register_view(r"preferences/optionaluser", views.OptionalUserView),
|
||||||
router.register_view(r'preferences/optionalmachine', views.OptionalMachineView),
|
router.register_view(r"preferences/optionalmachine", views.OptionalMachineView),
|
||||||
router.register_view(r'preferences/optionaltopologie', views.OptionalTopologieView),
|
router.register_view(r"preferences/optionaltopologie", views.OptionalTopologieView),
|
||||||
router.register_view(r'preferences/radiusoption', views.RadiusOptionView),
|
router.register_view(r"preferences/radiusoption", views.RadiusOptionView),
|
||||||
router.register_view(r'preferences/generaloption', views.GeneralOptionView),
|
router.register_view(r"preferences/generaloption", views.GeneralOptionView),
|
||||||
router.register_viewset(r'preferences/service', views.HomeServiceViewSet, base_name='homeservice'),
|
router.register_viewset(
|
||||||
router.register_view(r'preferences/assooption', views.AssoOptionView),
|
r"preferences/service", views.HomeServiceViewSet, base_name="homeservice"
|
||||||
router.register_view(r'preferences/homeoption', views.HomeOptionView),
|
),
|
||||||
router.register_view(r'preferences/mailmessageoption', views.MailMessageOptionView),
|
router.register_view(r"preferences/assooption", views.AssoOptionView),
|
||||||
|
router.register_view(r"preferences/homeoption", views.HomeOptionView),
|
||||||
|
router.register_view(r"preferences/mailmessageoption", views.MailMessageOptionView),
|
||||||
# TOPOLOGIE
|
# TOPOLOGIE
|
||||||
router.register_viewset(r'topologie/stack', views.StackViewSet)
|
router.register_viewset(r"topologie/stack", views.StackViewSet)
|
||||||
router.register_viewset(r'topologie/acesspoint', views.AccessPointViewSet)
|
router.register_viewset(r"topologie/acesspoint", views.AccessPointViewSet)
|
||||||
router.register_viewset(r'topologie/switch', views.SwitchViewSet)
|
router.register_viewset(r"topologie/switch", views.SwitchViewSet)
|
||||||
router.register_viewset(r'topologie/server', views.ServerViewSet)
|
router.register_viewset(r"topologie/server", views.ServerViewSet)
|
||||||
router.register_viewset(r'topologie/modelswitch', views.ModelSwitchViewSet)
|
router.register_viewset(r"topologie/modelswitch", views.ModelSwitchViewSet)
|
||||||
router.register_viewset(r'topologie/constructorswitch', views.ConstructorSwitchViewSet)
|
router.register_viewset(r"topologie/constructorswitch", views.ConstructorSwitchViewSet)
|
||||||
router.register_viewset(r'topologie/switchbay', views.SwitchBayViewSet)
|
router.register_viewset(r"topologie/switchbay", views.SwitchBayViewSet)
|
||||||
router.register_viewset(r'topologie/building', views.BuildingViewSet)
|
router.register_viewset(r"topologie/building", views.BuildingViewSet)
|
||||||
router.register_viewset(r'topologie/switchport', views.SwitchPortViewSet, base_name='switchport')
|
router.register_viewset(
|
||||||
router.register_viewset(r'topologie/portprofile', views.PortProfileViewSet, base_name='portprofile')
|
r"topologie/switchport", views.SwitchPortViewSet, base_name="switchport"
|
||||||
router.register_viewset(r'topologie/room', views.RoomViewSet)
|
)
|
||||||
router.register(r'topologie/portprofile', views.PortProfileViewSet)
|
router.register_viewset(
|
||||||
|
r"topologie/portprofile", views.PortProfileViewSet, base_name="portprofile"
|
||||||
|
)
|
||||||
|
router.register_viewset(r"topologie/room", views.RoomViewSet)
|
||||||
|
router.register(r"topologie/portprofile", views.PortProfileViewSet)
|
||||||
# USERS
|
# USERS
|
||||||
router.register_viewset(r'users/user', views.UserViewSet, base_name='user')
|
router.register_viewset(r"users/user", views.UserViewSet, base_name="user")
|
||||||
router.register_viewset(r'users/homecreation', views.HomeCreationViewSet, base_name='homecreation')
|
router.register_viewset(
|
||||||
router.register_viewset(r'users/normaluser', views.NormalUserViewSet, base_name='normaluser')
|
r"users/homecreation", views.HomeCreationViewSet, base_name="homecreation"
|
||||||
router.register_viewset(r'users/criticaluser', views.CriticalUserViewSet, base_name='criticaluser')
|
)
|
||||||
router.register_viewset(r'users/club', views.ClubViewSet)
|
router.register_viewset(
|
||||||
router.register_viewset(r'users/adherent', views.AdherentViewSet)
|
r"users/normaluser", views.NormalUserViewSet, base_name="normaluser"
|
||||||
router.register_viewset(r'users/serviceuser', views.ServiceUserViewSet)
|
)
|
||||||
router.register_viewset(r'users/school', views.SchoolViewSet)
|
router.register_viewset(
|
||||||
router.register_viewset(r'users/listright', views.ListRightViewSet)
|
r"users/criticaluser", views.CriticalUserViewSet, base_name="criticaluser"
|
||||||
router.register_viewset(r'users/shell', views.ShellViewSet, base_name='shell')
|
)
|
||||||
router.register_viewset(r'users/ban', views.BanViewSet)
|
router.register_viewset(r"users/club", views.ClubViewSet)
|
||||||
router.register_viewset(r'users/whitelist', views.WhitelistViewSet)
|
router.register_viewset(r"users/adherent", views.AdherentViewSet)
|
||||||
router.register_viewset(r'users/emailaddress', views.EMailAddressViewSet)
|
router.register_viewset(r"users/serviceuser", views.ServiceUserViewSet)
|
||||||
|
router.register_viewset(r"users/school", views.SchoolViewSet)
|
||||||
|
router.register_viewset(r"users/listright", views.ListRightViewSet)
|
||||||
|
router.register_viewset(r"users/shell", views.ShellViewSet, base_name="shell")
|
||||||
|
router.register_viewset(r"users/ban", views.BanViewSet)
|
||||||
|
router.register_viewset(r"users/whitelist", views.WhitelistViewSet)
|
||||||
|
router.register_viewset(r"users/emailaddress", views.EMailAddressViewSet)
|
||||||
# SERVICE REGEN
|
# SERVICE REGEN
|
||||||
router.register_viewset(r'services/regen', views.ServiceRegenViewSet, base_name='serviceregen')
|
router.register_viewset(
|
||||||
|
r"services/regen", views.ServiceRegenViewSet, base_name="serviceregen"
|
||||||
|
)
|
||||||
# DHCP
|
# DHCP
|
||||||
router.register_view(r'dhcp/hostmacip', views.HostMacIpView),
|
router.register_view(r"dhcp/hostmacip", views.HostMacIpView),
|
||||||
# LOCAL EMAILS
|
# LOCAL EMAILS
|
||||||
router.register_view(r'localemail/users', views.LocalEmailUsersView),
|
router.register_view(r"localemail/users", views.LocalEmailUsersView),
|
||||||
# Firewall
|
# Firewall
|
||||||
router.register_view(r'firewall/subnet-ports', views.SubnetPortsOpenView),
|
router.register_view(r"firewall/subnet-ports", views.SubnetPortsOpenView),
|
||||||
router.register_view(r'firewall/interface-ports', views.InterfacePortsOpenView),
|
router.register_view(r"firewall/interface-ports", views.InterfacePortsOpenView),
|
||||||
# Switches config
|
# Switches config
|
||||||
router.register_view(r'switchs/ports-config', views.SwitchPortView),
|
router.register_view(r"switchs/ports-config", views.SwitchPortView),
|
||||||
router.register_view(r'switchs/role', views.RoleView),
|
router.register_view(r"switchs/role", views.RoleView),
|
||||||
# Reminder
|
# Reminder
|
||||||
router.register_view(r'reminder/get-users', views.ReminderView),
|
router.register_view(r"reminder/get-users", views.ReminderView),
|
||||||
# DNS
|
# DNS
|
||||||
router.register_view(r'dns/zones', views.DNSZonesView),
|
router.register_view(r"dns/zones", views.DNSZonesView),
|
||||||
router.register_view(r'dns/reverse-zones', views.DNSReverseZonesView),
|
router.register_view(r"dns/reverse-zones", views.DNSReverseZonesView),
|
||||||
# MAILING
|
# MAILING
|
||||||
router.register_view(r'mailing/standard', views.StandardMailingView),
|
router.register_view(r"mailing/standard", views.StandardMailingView),
|
||||||
router.register_view(r'mailing/club', views.ClubMailingView),
|
router.register_view(r"mailing/club", views.ClubMailingView),
|
||||||
# TOKEN AUTHENTICATION
|
# TOKEN AUTHENTICATION
|
||||||
router.register_view(r'token-auth', views.ObtainExpiringAuthToken)
|
router.register_view(r"token-auth", views.ObtainExpiringAuthToken)
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [url(r"^", include(router.urls))]
|
||||||
url(r'^', include(router.urls)),
|
|
||||||
]
|
|
||||||
|
|
179
api/views.py
179
api/views.py
|
@ -52,12 +52,15 @@ from .permissions import ACLPermission
|
||||||
class FactureViewSet(viewsets.ReadOnlyModelViewSet):
|
class FactureViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `cotisations.models.Facture` objects.
|
"""Exposes list and details of `cotisations.models.Facture` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = cotisations.Facture.objects.all()
|
queryset = cotisations.Facture.objects.all()
|
||||||
serializer_class = serializers.FactureSerializer
|
serializer_class = serializers.FactureSerializer
|
||||||
|
|
||||||
|
|
||||||
class FactureViewSet(viewsets.ReadOnlyModelViewSet):
|
class FactureViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `cotisations.models.Facture` objects.
|
"""Exposes list and details of `cotisations.models.Facture` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = cotisations.BaseInvoice.objects.all()
|
queryset = cotisations.BaseInvoice.objects.all()
|
||||||
serializer_class = serializers.BaseInvoiceSerializer
|
serializer_class = serializers.BaseInvoiceSerializer
|
||||||
|
|
||||||
|
@ -65,6 +68,7 @@ class FactureViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class VenteViewSet(viewsets.ReadOnlyModelViewSet):
|
class VenteViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `cotisations.models.Vente` objects.
|
"""Exposes list and details of `cotisations.models.Vente` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = cotisations.Vente.objects.all()
|
queryset = cotisations.Vente.objects.all()
|
||||||
serializer_class = serializers.VenteSerializer
|
serializer_class = serializers.VenteSerializer
|
||||||
|
|
||||||
|
@ -72,6 +76,7 @@ class VenteViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class ArticleViewSet(viewsets.ReadOnlyModelViewSet):
|
class ArticleViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `cotisations.models.Article` objects.
|
"""Exposes list and details of `cotisations.models.Article` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = cotisations.Article.objects.all()
|
queryset = cotisations.Article.objects.all()
|
||||||
serializer_class = serializers.ArticleSerializer
|
serializer_class = serializers.ArticleSerializer
|
||||||
|
|
||||||
|
@ -79,6 +84,7 @@ class ArticleViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class BanqueViewSet(viewsets.ReadOnlyModelViewSet):
|
class BanqueViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `cotisations.models.Banque` objects.
|
"""Exposes list and details of `cotisations.models.Banque` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = cotisations.Banque.objects.all()
|
queryset = cotisations.Banque.objects.all()
|
||||||
serializer_class = serializers.BanqueSerializer
|
serializer_class = serializers.BanqueSerializer
|
||||||
|
|
||||||
|
@ -86,6 +92,7 @@ class BanqueViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class PaiementViewSet(viewsets.ReadOnlyModelViewSet):
|
class PaiementViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `cotisations.models.Paiement` objects.
|
"""Exposes list and details of `cotisations.models.Paiement` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = cotisations.Paiement.objects.all()
|
queryset = cotisations.Paiement.objects.all()
|
||||||
serializer_class = serializers.PaiementSerializer
|
serializer_class = serializers.PaiementSerializer
|
||||||
|
|
||||||
|
@ -93,6 +100,7 @@ class PaiementViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class CotisationViewSet(viewsets.ReadOnlyModelViewSet):
|
class CotisationViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `cotisations.models.Cotisation` objects.
|
"""Exposes list and details of `cotisations.models.Cotisation` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = cotisations.Cotisation.objects.all()
|
queryset = cotisations.Cotisation.objects.all()
|
||||||
serializer_class = serializers.CotisationSerializer
|
serializer_class = serializers.CotisationSerializer
|
||||||
|
|
||||||
|
@ -103,6 +111,7 @@ class CotisationViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class MachineViewSet(viewsets.ReadOnlyModelViewSet):
|
class MachineViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.Machine` objects.
|
"""Exposes list and details of `machines.models.Machine` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.Machine.objects.all()
|
queryset = machines.Machine.objects.all()
|
||||||
serializer_class = serializers.MachineSerializer
|
serializer_class = serializers.MachineSerializer
|
||||||
|
|
||||||
|
@ -110,6 +119,7 @@ class MachineViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class MachineTypeViewSet(viewsets.ReadOnlyModelViewSet):
|
class MachineTypeViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.MachineType` objects.
|
"""Exposes list and details of `machines.models.MachineType` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.MachineType.objects.all()
|
queryset = machines.MachineType.objects.all()
|
||||||
serializer_class = serializers.MachineTypeSerializer
|
serializer_class = serializers.MachineTypeSerializer
|
||||||
|
|
||||||
|
@ -117,6 +127,7 @@ class MachineTypeViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class IpTypeViewSet(viewsets.ReadOnlyModelViewSet):
|
class IpTypeViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.IpType` objects.
|
"""Exposes list and details of `machines.models.IpType` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.IpType.objects.all()
|
queryset = machines.IpType.objects.all()
|
||||||
serializer_class = serializers.IpTypeSerializer
|
serializer_class = serializers.IpTypeSerializer
|
||||||
|
|
||||||
|
@ -124,6 +135,7 @@ class IpTypeViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class VlanViewSet(viewsets.ReadOnlyModelViewSet):
|
class VlanViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.Vlan` objects.
|
"""Exposes list and details of `machines.models.Vlan` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.Vlan.objects.all()
|
queryset = machines.Vlan.objects.all()
|
||||||
serializer_class = serializers.VlanSerializer
|
serializer_class = serializers.VlanSerializer
|
||||||
|
|
||||||
|
@ -131,6 +143,7 @@ class VlanViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class NasViewSet(viewsets.ReadOnlyModelViewSet):
|
class NasViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.Nas` objects.
|
"""Exposes list and details of `machines.models.Nas` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.Nas.objects.all()
|
queryset = machines.Nas.objects.all()
|
||||||
serializer_class = serializers.NasSerializer
|
serializer_class = serializers.NasSerializer
|
||||||
|
|
||||||
|
@ -138,6 +151,7 @@ class NasViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class SOAViewSet(viewsets.ReadOnlyModelViewSet):
|
class SOAViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.SOA` objects.
|
"""Exposes list and details of `machines.models.SOA` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.SOA.objects.all()
|
queryset = machines.SOA.objects.all()
|
||||||
serializer_class = serializers.SOASerializer
|
serializer_class = serializers.SOASerializer
|
||||||
|
|
||||||
|
@ -145,6 +159,7 @@ class SOAViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class ExtensionViewSet(viewsets.ReadOnlyModelViewSet):
|
class ExtensionViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.Extension` objects.
|
"""Exposes list and details of `machines.models.Extension` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.Extension.objects.all()
|
queryset = machines.Extension.objects.all()
|
||||||
serializer_class = serializers.ExtensionSerializer
|
serializer_class = serializers.ExtensionSerializer
|
||||||
|
|
||||||
|
@ -152,6 +167,7 @@ class ExtensionViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class MxViewSet(viewsets.ReadOnlyModelViewSet):
|
class MxViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.Mx` objects.
|
"""Exposes list and details of `machines.models.Mx` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.Mx.objects.all()
|
queryset = machines.Mx.objects.all()
|
||||||
serializer_class = serializers.MxSerializer
|
serializer_class = serializers.MxSerializer
|
||||||
|
|
||||||
|
@ -159,6 +175,7 @@ class MxViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class NsViewSet(viewsets.ReadOnlyModelViewSet):
|
class NsViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.Ns` objects.
|
"""Exposes list and details of `machines.models.Ns` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.Ns.objects.all()
|
queryset = machines.Ns.objects.all()
|
||||||
serializer_class = serializers.NsSerializer
|
serializer_class = serializers.NsSerializer
|
||||||
|
|
||||||
|
@ -166,6 +183,7 @@ class NsViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class TxtViewSet(viewsets.ReadOnlyModelViewSet):
|
class TxtViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.Txt` objects.
|
"""Exposes list and details of `machines.models.Txt` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.Txt.objects.all()
|
queryset = machines.Txt.objects.all()
|
||||||
serializer_class = serializers.TxtSerializer
|
serializer_class = serializers.TxtSerializer
|
||||||
|
|
||||||
|
@ -173,6 +191,7 @@ class TxtViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class DNameViewSet(viewsets.ReadOnlyModelViewSet):
|
class DNameViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.DName` objects.
|
"""Exposes list and details of `machines.models.DName` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.DName.objects.all()
|
queryset = machines.DName.objects.all()
|
||||||
serializer_class = serializers.DNameSerializer
|
serializer_class = serializers.DNameSerializer
|
||||||
|
|
||||||
|
@ -180,6 +199,7 @@ class DNameViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class SrvViewSet(viewsets.ReadOnlyModelViewSet):
|
class SrvViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.Srv` objects.
|
"""Exposes list and details of `machines.models.Srv` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.Srv.objects.all()
|
queryset = machines.Srv.objects.all()
|
||||||
serializer_class = serializers.SrvSerializer
|
serializer_class = serializers.SrvSerializer
|
||||||
|
|
||||||
|
@ -187,6 +207,7 @@ class SrvViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class SshFpViewSet(viewsets.ReadOnlyModelViewSet):
|
class SshFpViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.SshFp` objects.
|
"""Exposes list and details of `machines.models.SshFp` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.SshFp.objects.all()
|
queryset = machines.SshFp.objects.all()
|
||||||
serializer_class = serializers.SshFpSerializer
|
serializer_class = serializers.SshFpSerializer
|
||||||
|
|
||||||
|
@ -194,6 +215,7 @@ class SshFpViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class InterfaceViewSet(viewsets.ReadOnlyModelViewSet):
|
class InterfaceViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.Interface` objects.
|
"""Exposes list and details of `machines.models.Interface` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.Interface.objects.all()
|
queryset = machines.Interface.objects.all()
|
||||||
serializer_class = serializers.InterfaceSerializer
|
serializer_class = serializers.InterfaceSerializer
|
||||||
|
|
||||||
|
@ -201,6 +223,7 @@ class InterfaceViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class Ipv6ListViewSet(viewsets.ReadOnlyModelViewSet):
|
class Ipv6ListViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.Ipv6List` objects.
|
"""Exposes list and details of `machines.models.Ipv6List` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.Ipv6List.objects.all()
|
queryset = machines.Ipv6List.objects.all()
|
||||||
serializer_class = serializers.Ipv6ListSerializer
|
serializer_class = serializers.Ipv6ListSerializer
|
||||||
|
|
||||||
|
@ -208,6 +231,7 @@ class Ipv6ListViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class DomainViewSet(viewsets.ReadOnlyModelViewSet):
|
class DomainViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.Domain` objects.
|
"""Exposes list and details of `machines.models.Domain` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.Domain.objects.all()
|
queryset = machines.Domain.objects.all()
|
||||||
serializer_class = serializers.DomainSerializer
|
serializer_class = serializers.DomainSerializer
|
||||||
|
|
||||||
|
@ -215,6 +239,7 @@ class DomainViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class IpListViewSet(viewsets.ReadOnlyModelViewSet):
|
class IpListViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.IpList` objects.
|
"""Exposes list and details of `machines.models.IpList` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.IpList.objects.all()
|
queryset = machines.IpList.objects.all()
|
||||||
serializer_class = serializers.IpListSerializer
|
serializer_class = serializers.IpListSerializer
|
||||||
|
|
||||||
|
@ -222,6 +247,7 @@ class IpListViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class ServiceViewSet(viewsets.ReadOnlyModelViewSet):
|
class ServiceViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.Service` objects.
|
"""Exposes list and details of `machines.models.Service` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.Service.objects.all()
|
queryset = machines.Service.objects.all()
|
||||||
serializer_class = serializers.ServiceSerializer
|
serializer_class = serializers.ServiceSerializer
|
||||||
|
|
||||||
|
@ -229,6 +255,7 @@ class ServiceViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class ServiceLinkViewSet(viewsets.ReadOnlyModelViewSet):
|
class ServiceLinkViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.Service_link` objects.
|
"""Exposes list and details of `machines.models.Service_link` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.Service_link.objects.all()
|
queryset = machines.Service_link.objects.all()
|
||||||
serializer_class = serializers.ServiceLinkSerializer
|
serializer_class = serializers.ServiceLinkSerializer
|
||||||
|
|
||||||
|
@ -237,6 +264,7 @@ class OuverturePortListViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.OuverturePortList`
|
"""Exposes list and details of `machines.models.OuverturePortList`
|
||||||
objects.
|
objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.OuverturePortList.objects.all()
|
queryset = machines.OuverturePortList.objects.all()
|
||||||
serializer_class = serializers.OuverturePortListSerializer
|
serializer_class = serializers.OuverturePortListSerializer
|
||||||
|
|
||||||
|
@ -244,6 +272,7 @@ class OuverturePortListViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class OuverturePortViewSet(viewsets.ReadOnlyModelViewSet):
|
class OuverturePortViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.OuverturePort` objects.
|
"""Exposes list and details of `machines.models.OuverturePort` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.OuverturePort.objects.all()
|
queryset = machines.OuverturePort.objects.all()
|
||||||
serializer_class = serializers.OuverturePortSerializer
|
serializer_class = serializers.OuverturePortSerializer
|
||||||
|
|
||||||
|
@ -251,6 +280,7 @@ class OuverturePortViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class RoleViewSet(viewsets.ReadOnlyModelViewSet):
|
class RoleViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.Machine` objects.
|
"""Exposes list and details of `machines.models.Machine` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.Role.objects.all()
|
queryset = machines.Role.objects.all()
|
||||||
serializer_class = serializers.RoleSerializer
|
serializer_class = serializers.RoleSerializer
|
||||||
|
|
||||||
|
@ -259,11 +289,13 @@ class RoleViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
# Those views differ a bit because there is only one object
|
# Those views differ a bit because there is only one object
|
||||||
# to display, so we don't bother with the listing part
|
# to display, so we don't bother with the listing part
|
||||||
|
|
||||||
|
|
||||||
class OptionalUserView(generics.RetrieveAPIView):
|
class OptionalUserView(generics.RetrieveAPIView):
|
||||||
"""Exposes details of `preferences.models.` settings.
|
"""Exposes details of `preferences.models.` settings.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
permission_classes = (ACLPermission,)
|
permission_classes = (ACLPermission,)
|
||||||
perms_map = {'GET': [preferences.OptionalUser.can_view_all]}
|
perms_map = {"GET": [preferences.OptionalUser.can_view_all]}
|
||||||
serializer_class = serializers.OptionalUserSerializer
|
serializer_class = serializers.OptionalUserSerializer
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
|
@ -273,8 +305,9 @@ class OptionalUserView(generics.RetrieveAPIView):
|
||||||
class OptionalMachineView(generics.RetrieveAPIView):
|
class OptionalMachineView(generics.RetrieveAPIView):
|
||||||
"""Exposes details of `preferences.models.OptionalMachine` settings.
|
"""Exposes details of `preferences.models.OptionalMachine` settings.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
permission_classes = (ACLPermission,)
|
permission_classes = (ACLPermission,)
|
||||||
perms_map = {'GET': [preferences.OptionalMachine.can_view_all]}
|
perms_map = {"GET": [preferences.OptionalMachine.can_view_all]}
|
||||||
serializer_class = serializers.OptionalMachineSerializer
|
serializer_class = serializers.OptionalMachineSerializer
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
|
@ -284,8 +317,9 @@ class OptionalMachineView(generics.RetrieveAPIView):
|
||||||
class OptionalTopologieView(generics.RetrieveAPIView):
|
class OptionalTopologieView(generics.RetrieveAPIView):
|
||||||
"""Exposes details of `preferences.models.OptionalTopologie` settings.
|
"""Exposes details of `preferences.models.OptionalTopologie` settings.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
permission_classes = (ACLPermission,)
|
permission_classes = (ACLPermission,)
|
||||||
perms_map = {'GET': [preferences.OptionalTopologie.can_view_all]}
|
perms_map = {"GET": [preferences.OptionalTopologie.can_view_all]}
|
||||||
serializer_class = serializers.OptionalTopologieSerializer
|
serializer_class = serializers.OptionalTopologieSerializer
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
|
@ -295,8 +329,9 @@ class OptionalTopologieView(generics.RetrieveAPIView):
|
||||||
class RadiusOptionView(generics.RetrieveAPIView):
|
class RadiusOptionView(generics.RetrieveAPIView):
|
||||||
"""Exposes details of `preferences.models.OptionalTopologie` settings.
|
"""Exposes details of `preferences.models.OptionalTopologie` settings.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
permission_classes = (ACLPermission,)
|
permission_classes = (ACLPermission,)
|
||||||
perms_map = {'GET': [preferences.RadiusOption.can_view_all]}
|
perms_map = {"GET": [preferences.RadiusOption.can_view_all]}
|
||||||
serializer_class = serializers.RadiusOptionSerializer
|
serializer_class = serializers.RadiusOptionSerializer
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
|
@ -306,8 +341,9 @@ class RadiusOptionView(generics.RetrieveAPIView):
|
||||||
class GeneralOptionView(generics.RetrieveAPIView):
|
class GeneralOptionView(generics.RetrieveAPIView):
|
||||||
"""Exposes details of `preferences.models.GeneralOption` settings.
|
"""Exposes details of `preferences.models.GeneralOption` settings.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
permission_classes = (ACLPermission,)
|
permission_classes = (ACLPermission,)
|
||||||
perms_map = {'GET': [preferences.GeneralOption.can_view_all]}
|
perms_map = {"GET": [preferences.GeneralOption.can_view_all]}
|
||||||
serializer_class = serializers.GeneralOptionSerializer
|
serializer_class = serializers.GeneralOptionSerializer
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
|
@ -317,6 +353,7 @@ class GeneralOptionView(generics.RetrieveAPIView):
|
||||||
class HomeServiceViewSet(viewsets.ReadOnlyModelViewSet):
|
class HomeServiceViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `preferences.models.Service` objects.
|
"""Exposes list and details of `preferences.models.Service` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = preferences.Service.objects.all()
|
queryset = preferences.Service.objects.all()
|
||||||
serializer_class = serializers.HomeServiceSerializer
|
serializer_class = serializers.HomeServiceSerializer
|
||||||
|
|
||||||
|
@ -324,8 +361,9 @@ class HomeServiceViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class AssoOptionView(generics.RetrieveAPIView):
|
class AssoOptionView(generics.RetrieveAPIView):
|
||||||
"""Exposes details of `preferences.models.AssoOption` settings.
|
"""Exposes details of `preferences.models.AssoOption` settings.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
permission_classes = (ACLPermission,)
|
permission_classes = (ACLPermission,)
|
||||||
perms_map = {'GET': [preferences.AssoOption.can_view_all]}
|
perms_map = {"GET": [preferences.AssoOption.can_view_all]}
|
||||||
serializer_class = serializers.AssoOptionSerializer
|
serializer_class = serializers.AssoOptionSerializer
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
|
@ -335,8 +373,9 @@ class AssoOptionView(generics.RetrieveAPIView):
|
||||||
class HomeOptionView(generics.RetrieveAPIView):
|
class HomeOptionView(generics.RetrieveAPIView):
|
||||||
"""Exposes details of `preferences.models.HomeOption` settings.
|
"""Exposes details of `preferences.models.HomeOption` settings.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
permission_classes = (ACLPermission,)
|
permission_classes = (ACLPermission,)
|
||||||
perms_map = {'GET': [preferences.HomeOption.can_view_all]}
|
perms_map = {"GET": [preferences.HomeOption.can_view_all]}
|
||||||
serializer_class = serializers.HomeOptionSerializer
|
serializer_class = serializers.HomeOptionSerializer
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
|
@ -346,8 +385,9 @@ class HomeOptionView(generics.RetrieveAPIView):
|
||||||
class MailMessageOptionView(generics.RetrieveAPIView):
|
class MailMessageOptionView(generics.RetrieveAPIView):
|
||||||
"""Exposes details of `preferences.models.MailMessageOption` settings.
|
"""Exposes details of `preferences.models.MailMessageOption` settings.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
permission_classes = (ACLPermission,)
|
permission_classes = (ACLPermission,)
|
||||||
perms_map = {'GET': [preferences.MailMessageOption.can_view_all]}
|
perms_map = {"GET": [preferences.MailMessageOption.can_view_all]}
|
||||||
serializer_class = serializers.MailMessageOptionSerializer
|
serializer_class = serializers.MailMessageOptionSerializer
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
|
@ -360,6 +400,7 @@ class MailMessageOptionView(generics.RetrieveAPIView):
|
||||||
class StackViewSet(viewsets.ReadOnlyModelViewSet):
|
class StackViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `topologie.models.Stack` objects.
|
"""Exposes list and details of `topologie.models.Stack` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = topologie.Stack.objects.all()
|
queryset = topologie.Stack.objects.all()
|
||||||
serializer_class = serializers.StackSerializer
|
serializer_class = serializers.StackSerializer
|
||||||
|
|
||||||
|
@ -367,6 +408,7 @@ class StackViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class AccessPointViewSet(viewsets.ReadOnlyModelViewSet):
|
class AccessPointViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `topologie.models.AccessPoint` objects.
|
"""Exposes list and details of `topologie.models.AccessPoint` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = topologie.AccessPoint.objects.all()
|
queryset = topologie.AccessPoint.objects.all()
|
||||||
serializer_class = serializers.AccessPointSerializer
|
serializer_class = serializers.AccessPointSerializer
|
||||||
|
|
||||||
|
@ -374,6 +416,7 @@ class AccessPointViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class SwitchViewSet(viewsets.ReadOnlyModelViewSet):
|
class SwitchViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `topologie.models.Switch` objects.
|
"""Exposes list and details of `topologie.models.Switch` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = topologie.Switch.objects.all()
|
queryset = topologie.Switch.objects.all()
|
||||||
serializer_class = serializers.SwitchSerializer
|
serializer_class = serializers.SwitchSerializer
|
||||||
|
|
||||||
|
@ -381,6 +424,7 @@ class SwitchViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class ServerViewSet(viewsets.ReadOnlyModelViewSet):
|
class ServerViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `topologie.models.Server` objects.
|
"""Exposes list and details of `topologie.models.Server` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = topologie.Server.objects.all()
|
queryset = topologie.Server.objects.all()
|
||||||
serializer_class = serializers.ServerSerializer
|
serializer_class = serializers.ServerSerializer
|
||||||
|
|
||||||
|
@ -388,6 +432,7 @@ class ServerViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class ModelSwitchViewSet(viewsets.ReadOnlyModelViewSet):
|
class ModelSwitchViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `topologie.models.ModelSwitch` objects.
|
"""Exposes list and details of `topologie.models.ModelSwitch` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = topologie.ModelSwitch.objects.all()
|
queryset = topologie.ModelSwitch.objects.all()
|
||||||
serializer_class = serializers.ModelSwitchSerializer
|
serializer_class = serializers.ModelSwitchSerializer
|
||||||
|
|
||||||
|
@ -396,6 +441,7 @@ class ConstructorSwitchViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `topologie.models.ConstructorSwitch`
|
"""Exposes list and details of `topologie.models.ConstructorSwitch`
|
||||||
objects.
|
objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = topologie.ConstructorSwitch.objects.all()
|
queryset = topologie.ConstructorSwitch.objects.all()
|
||||||
serializer_class = serializers.ConstructorSwitchSerializer
|
serializer_class = serializers.ConstructorSwitchSerializer
|
||||||
|
|
||||||
|
@ -403,6 +449,7 @@ class ConstructorSwitchViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class SwitchBayViewSet(viewsets.ReadOnlyModelViewSet):
|
class SwitchBayViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `topologie.models.SwitchBay` objects.
|
"""Exposes list and details of `topologie.models.SwitchBay` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = topologie.SwitchBay.objects.all()
|
queryset = topologie.SwitchBay.objects.all()
|
||||||
serializer_class = serializers.SwitchBaySerializer
|
serializer_class = serializers.SwitchBaySerializer
|
||||||
|
|
||||||
|
@ -410,6 +457,7 @@ class SwitchBayViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class BuildingViewSet(viewsets.ReadOnlyModelViewSet):
|
class BuildingViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `topologie.models.Building` objects.
|
"""Exposes list and details of `topologie.models.Building` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = topologie.Building.objects.all()
|
queryset = topologie.Building.objects.all()
|
||||||
serializer_class = serializers.BuildingSerializer
|
serializer_class = serializers.BuildingSerializer
|
||||||
|
|
||||||
|
@ -417,6 +465,7 @@ class BuildingViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class SwitchPortViewSet(viewsets.ReadOnlyModelViewSet):
|
class SwitchPortViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `topologie.models.Port` objects.
|
"""Exposes list and details of `topologie.models.Port` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = topologie.Port.objects.all()
|
queryset = topologie.Port.objects.all()
|
||||||
serializer_class = serializers.SwitchPortSerializer
|
serializer_class = serializers.SwitchPortSerializer
|
||||||
|
|
||||||
|
@ -424,6 +473,7 @@ class SwitchPortViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class PortProfileViewSet(viewsets.ReadOnlyModelViewSet):
|
class PortProfileViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `topologie.models.PortProfile` objects.
|
"""Exposes list and details of `topologie.models.PortProfile` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = topologie.PortProfile.objects.all()
|
queryset = topologie.PortProfile.objects.all()
|
||||||
serializer_class = serializers.PortProfileSerializer
|
serializer_class = serializers.PortProfileSerializer
|
||||||
|
|
||||||
|
@ -431,6 +481,7 @@ class PortProfileViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class RoomViewSet(viewsets.ReadOnlyModelViewSet):
|
class RoomViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `topologie.models.Room` objects.
|
"""Exposes list and details of `topologie.models.Room` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = topologie.Room.objects.all()
|
queryset = topologie.Room.objects.all()
|
||||||
serializer_class = serializers.RoomSerializer
|
serializer_class = serializers.RoomSerializer
|
||||||
|
|
||||||
|
@ -438,6 +489,7 @@ class RoomViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class PortProfileViewSet(viewsets.ReadOnlyModelViewSet):
|
class PortProfileViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `topologie.models.PortProfile` objects.
|
"""Exposes list and details of `topologie.models.PortProfile` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = topologie.PortProfile.objects.all()
|
queryset = topologie.PortProfile.objects.all()
|
||||||
serializer_class = serializers.PortProfileSerializer
|
serializer_class = serializers.PortProfileSerializer
|
||||||
|
|
||||||
|
@ -448,6 +500,7 @@ class PortProfileViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class UserViewSet(viewsets.ReadOnlyModelViewSet):
|
class UserViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `users.models.Users` objects.
|
"""Exposes list and details of `users.models.Users` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = users.User.objects.all()
|
queryset = users.User.objects.all()
|
||||||
serializer_class = serializers.UserSerializer
|
serializer_class = serializers.UserSerializer
|
||||||
|
|
||||||
|
@ -455,18 +508,25 @@ class UserViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class HomeCreationViewSet(viewsets.ReadOnlyModelViewSet):
|
class HomeCreationViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes infos of `users.models.Users` objects to create homes.
|
"""Exposes infos of `users.models.Users` objects to create homes.
|
||||||
"""
|
"""
|
||||||
queryset = users.User.objects.exclude(Q(state=users.User.STATE_DISABLED) | Q(state=users.User.STATE_NOT_YET_ACTIVE) | Q(state=users.User.STATE_FULL_ARCHIVE))
|
|
||||||
|
queryset = users.User.objects.exclude(
|
||||||
|
Q(state=users.User.STATE_DISABLED)
|
||||||
|
| Q(state=users.User.STATE_NOT_YET_ACTIVE)
|
||||||
|
| Q(state=users.User.STATE_FULL_ARCHIVE)
|
||||||
|
)
|
||||||
serializer_class = serializers.BasicUserSerializer
|
serializer_class = serializers.BasicUserSerializer
|
||||||
|
|
||||||
|
|
||||||
class NormalUserViewSet(viewsets.ReadOnlyModelViewSet):
|
class NormalUserViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes infos of `users.models.Users`without specific rights objects."""
|
"""Exposes infos of `users.models.Users`without specific rights objects."""
|
||||||
|
|
||||||
queryset = users.User.objects.exclude(groups__listright__critical=True).distinct()
|
queryset = users.User.objects.exclude(groups__listright__critical=True).distinct()
|
||||||
serializer_class = serializers.BasicUserSerializer
|
serializer_class = serializers.BasicUserSerializer
|
||||||
|
|
||||||
|
|
||||||
class CriticalUserViewSet(viewsets.ReadOnlyModelViewSet):
|
class CriticalUserViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes infos of `users.models.Users`without specific rights objects."""
|
"""Exposes infos of `users.models.Users`without specific rights objects."""
|
||||||
|
|
||||||
queryset = users.User.objects.filter(groups__listright__critical=True).distinct()
|
queryset = users.User.objects.filter(groups__listright__critical=True).distinct()
|
||||||
serializer_class = serializers.BasicUserSerializer
|
serializer_class = serializers.BasicUserSerializer
|
||||||
|
|
||||||
|
@ -474,6 +534,7 @@ class CriticalUserViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class ClubViewSet(viewsets.ReadOnlyModelViewSet):
|
class ClubViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `users.models.Club` objects.
|
"""Exposes list and details of `users.models.Club` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = users.Club.objects.all()
|
queryset = users.Club.objects.all()
|
||||||
serializer_class = serializers.ClubSerializer
|
serializer_class = serializers.ClubSerializer
|
||||||
|
|
||||||
|
@ -481,6 +542,7 @@ class ClubViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class AdherentViewSet(viewsets.ReadOnlyModelViewSet):
|
class AdherentViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `users.models.Adherent` objects.
|
"""Exposes list and details of `users.models.Adherent` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = users.Adherent.objects.all()
|
queryset = users.Adherent.objects.all()
|
||||||
serializer_class = serializers.AdherentSerializer
|
serializer_class = serializers.AdherentSerializer
|
||||||
|
|
||||||
|
@ -488,6 +550,7 @@ class AdherentViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class ServiceUserViewSet(viewsets.ReadOnlyModelViewSet):
|
class ServiceUserViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `users.models.ServiceUser` objects.
|
"""Exposes list and details of `users.models.ServiceUser` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = users.ServiceUser.objects.all()
|
queryset = users.ServiceUser.objects.all()
|
||||||
serializer_class = serializers.ServiceUserSerializer
|
serializer_class = serializers.ServiceUserSerializer
|
||||||
|
|
||||||
|
@ -495,6 +558,7 @@ class ServiceUserViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class SchoolViewSet(viewsets.ReadOnlyModelViewSet):
|
class SchoolViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `users.models.School` objects.
|
"""Exposes list and details of `users.models.School` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = users.School.objects.all()
|
queryset = users.School.objects.all()
|
||||||
serializer_class = serializers.SchoolSerializer
|
serializer_class = serializers.SchoolSerializer
|
||||||
|
|
||||||
|
@ -502,6 +566,7 @@ class SchoolViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class ListRightViewSet(viewsets.ReadOnlyModelViewSet):
|
class ListRightViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `users.models.ListRight` objects.
|
"""Exposes list and details of `users.models.ListRight` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = users.ListRight.objects.all()
|
queryset = users.ListRight.objects.all()
|
||||||
serializer_class = serializers.ListRightSerializer
|
serializer_class = serializers.ListRightSerializer
|
||||||
|
|
||||||
|
@ -509,6 +574,7 @@ class ListRightViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class ShellViewSet(viewsets.ReadOnlyModelViewSet):
|
class ShellViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `users.models.ListShell` objects.
|
"""Exposes list and details of `users.models.ListShell` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = users.ListShell.objects.all()
|
queryset = users.ListShell.objects.all()
|
||||||
serializer_class = serializers.ShellSerializer
|
serializer_class = serializers.ShellSerializer
|
||||||
|
|
||||||
|
@ -516,6 +582,7 @@ class ShellViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class BanViewSet(viewsets.ReadOnlyModelViewSet):
|
class BanViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `users.models.Ban` objects.
|
"""Exposes list and details of `users.models.Ban` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = users.Ban.objects.all()
|
queryset = users.Ban.objects.all()
|
||||||
serializer_class = serializers.BanSerializer
|
serializer_class = serializers.BanSerializer
|
||||||
|
|
||||||
|
@ -523,6 +590,7 @@ class BanViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class WhitelistViewSet(viewsets.ReadOnlyModelViewSet):
|
class WhitelistViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `users.models.Whitelist` objects.
|
"""Exposes list and details of `users.models.Whitelist` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = users.Whitelist.objects.all()
|
queryset = users.Whitelist.objects.all()
|
||||||
serializer_class = serializers.WhitelistSerializer
|
serializer_class = serializers.WhitelistSerializer
|
||||||
|
|
||||||
|
@ -530,14 +598,13 @@ class WhitelistViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class EMailAddressViewSet(viewsets.ReadOnlyModelViewSet):
|
class EMailAddressViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `users.models.EMailAddress` objects.
|
"""Exposes list and details of `users.models.EMailAddress` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
serializer_class = serializers.EMailAddressSerializer
|
serializer_class = serializers.EMailAddressSerializer
|
||||||
queryset = users.EMailAddress.objects.none()
|
queryset = users.EMailAddress.objects.none()
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
if preferences.OptionalUser.get_cached_value(
|
if preferences.OptionalUser.get_cached_value("local_email_accounts_enabled"):
|
||||||
'local_email_accounts_enabled'):
|
return users.EMailAddress.objects.filter(user__local_email_enabled=True)
|
||||||
return (users.EMailAddress.objects
|
|
||||||
.filter(user__local_email_enabled=True))
|
|
||||||
else:
|
else:
|
||||||
return users.EMailAddress.objects.none()
|
return users.EMailAddress.objects.none()
|
||||||
|
|
||||||
|
@ -548,34 +615,47 @@ class EMailAddressViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class ServiceRegenViewSet(viewsets.ModelViewSet):
|
class ServiceRegenViewSet(viewsets.ModelViewSet):
|
||||||
"""Exposes list and details of the services to regen
|
"""Exposes list and details of the services to regen
|
||||||
"""
|
"""
|
||||||
|
|
||||||
serializer_class = serializers.ServiceRegenSerializer
|
serializer_class = serializers.ServiceRegenSerializer
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
queryset = machines.Service_link.objects.select_related(
|
queryset = machines.Service_link.objects.select_related(
|
||||||
'server__domain'
|
"server__domain"
|
||||||
).select_related(
|
).select_related("service")
|
||||||
'service'
|
if "hostname" in self.request.GET:
|
||||||
)
|
hostname = self.request.GET["hostname"]
|
||||||
if 'hostname' in self.request.GET:
|
|
||||||
hostname = self.request.GET['hostname']
|
|
||||||
queryset = queryset.filter(server__domain__name__iexact=hostname)
|
queryset = queryset.filter(server__domain__name__iexact=hostname)
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
# Config des switches
|
# Config des switches
|
||||||
|
|
||||||
|
|
||||||
class SwitchPortView(generics.ListAPIView):
|
class SwitchPortView(generics.ListAPIView):
|
||||||
"""Output each port of a switch, to be serialized with
|
"""Output each port of a switch, to be serialized with
|
||||||
additionnal informations (profiles etc)
|
additionnal informations (profiles etc)
|
||||||
"""
|
"""
|
||||||
queryset = topologie.Switch.objects.all().select_related("switchbay").select_related("model__constructor").prefetch_related("ports__custom_profile__vlan_tagged").prefetch_related("ports__custom_profile__vlan_untagged").prefetch_related("ports__machine_interface__domain__extension").prefetch_related("ports__room")
|
|
||||||
|
queryset = (
|
||||||
|
topologie.Switch.objects.all()
|
||||||
|
.select_related("switchbay")
|
||||||
|
.select_related("model__constructor")
|
||||||
|
.prefetch_related("ports__custom_profile__vlan_tagged")
|
||||||
|
.prefetch_related("ports__custom_profile__vlan_untagged")
|
||||||
|
.prefetch_related("ports__machine_interface__domain__extension")
|
||||||
|
.prefetch_related("ports__room")
|
||||||
|
)
|
||||||
|
|
||||||
serializer_class = serializers.SwitchPortSerializer
|
serializer_class = serializers.SwitchPortSerializer
|
||||||
|
|
||||||
|
|
||||||
# Rappel fin adhésion
|
# Rappel fin adhésion
|
||||||
|
|
||||||
|
|
||||||
class ReminderView(generics.ListAPIView):
|
class ReminderView(generics.ListAPIView):
|
||||||
"""Output for users to remind an end of their subscription.
|
"""Output for users to remind an end of their subscription.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = preferences.Reminder.objects.all()
|
queryset = preferences.Reminder.objects.all()
|
||||||
serializer_class = serializers.ReminderSerializer
|
serializer_class = serializers.ReminderSerializer
|
||||||
|
|
||||||
|
@ -583,7 +663,8 @@ class ReminderView(generics.ListAPIView):
|
||||||
class RoleView(generics.ListAPIView):
|
class RoleView(generics.ListAPIView):
|
||||||
"""Output of roles for each server
|
"""Output of roles for each server
|
||||||
"""
|
"""
|
||||||
queryset = machines.Role.objects.all().prefetch_related('servers')
|
|
||||||
|
queryset = machines.Role.objects.all().prefetch_related("servers")
|
||||||
serializer_class = serializers.RoleSerializer
|
serializer_class = serializers.RoleSerializer
|
||||||
|
|
||||||
|
|
||||||
|
@ -593,13 +674,12 @@ class RoleView(generics.ListAPIView):
|
||||||
class LocalEmailUsersView(generics.ListAPIView):
|
class LocalEmailUsersView(generics.ListAPIView):
|
||||||
"""Exposes all the aliases of the users that activated the internal address
|
"""Exposes all the aliases of the users that activated the internal address
|
||||||
"""
|
"""
|
||||||
|
|
||||||
serializer_class = serializers.LocalEmailUsersSerializer
|
serializer_class = serializers.LocalEmailUsersSerializer
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
if preferences.OptionalUser.get_cached_value(
|
if preferences.OptionalUser.get_cached_value("local_email_accounts_enabled"):
|
||||||
'local_email_accounts_enabled'):
|
return users.User.objects.filter(local_email_enabled=True)
|
||||||
return (users.User.objects
|
|
||||||
.filter(local_email_enabled=True))
|
|
||||||
else:
|
else:
|
||||||
return users.User.objects.none()
|
return users.User.objects.none()
|
||||||
|
|
||||||
|
@ -611,6 +691,7 @@ class HostMacIpView(generics.ListAPIView):
|
||||||
"""Exposes the associations between hostname, mac address and IPv4 in
|
"""Exposes the associations between hostname, mac address and IPv4 in
|
||||||
order to build the DHCP lease files.
|
order to build the DHCP lease files.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
serializer_class = serializers.HostMacIpSerializer
|
serializer_class = serializers.HostMacIpSerializer
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
|
@ -619,6 +700,7 @@ class HostMacIpView(generics.ListAPIView):
|
||||||
|
|
||||||
# Firewall
|
# Firewall
|
||||||
|
|
||||||
|
|
||||||
class SubnetPortsOpenView(generics.ListAPIView):
|
class SubnetPortsOpenView(generics.ListAPIView):
|
||||||
queryset = machines.IpType.objects.all()
|
queryset = machines.IpType.objects.all()
|
||||||
serializer_class = serializers.SubnetPortsOpenSerializer
|
serializer_class = serializers.SubnetPortsOpenSerializer
|
||||||
|
@ -636,14 +718,19 @@ class DNSZonesView(generics.ListAPIView):
|
||||||
"""Exposes the detailed information about each extension (hostnames,
|
"""Exposes the detailed information about each extension (hostnames,
|
||||||
IPs, DNS records, etc.) in order to build the DNS zone files.
|
IPs, DNS records, etc.) in order to build the DNS zone files.
|
||||||
"""
|
"""
|
||||||
queryset = (machines.Extension.objects
|
|
||||||
.prefetch_related('soa')
|
queryset = (
|
||||||
.prefetch_related('ns_set').prefetch_related('ns_set__ns')
|
machines.Extension.objects.prefetch_related("soa")
|
||||||
.prefetch_related('origin')
|
.prefetch_related("ns_set")
|
||||||
.prefetch_related('mx_set').prefetch_related('mx_set__name')
|
.prefetch_related("ns_set__ns")
|
||||||
.prefetch_related('txt_set')
|
.prefetch_related("origin")
|
||||||
.prefetch_related('srv_set').prefetch_related('srv_set__target')
|
.prefetch_related("mx_set")
|
||||||
.all())
|
.prefetch_related("mx_set__name")
|
||||||
|
.prefetch_related("txt_set")
|
||||||
|
.prefetch_related("srv_set")
|
||||||
|
.prefetch_related("srv_set__target")
|
||||||
|
.all()
|
||||||
|
)
|
||||||
serializer_class = serializers.DNSZonesSerializer
|
serializer_class = serializers.DNSZonesSerializer
|
||||||
|
|
||||||
|
|
||||||
|
@ -651,7 +738,8 @@ class DNSReverseZonesView(generics.ListAPIView):
|
||||||
"""Exposes the detailed information about each extension (hostnames,
|
"""Exposes the detailed information about each extension (hostnames,
|
||||||
IPs, DNS records, etc.) in order to build the DNS zone files.
|
IPs, DNS records, etc.) in order to build the DNS zone files.
|
||||||
"""
|
"""
|
||||||
queryset = (machines.IpType.objects.all())
|
|
||||||
|
queryset = machines.IpType.objects.all()
|
||||||
serializer_class = serializers.DNSReverseZonesSerializer
|
serializer_class = serializers.DNSReverseZonesSerializer
|
||||||
|
|
||||||
|
|
||||||
|
@ -662,13 +750,16 @@ class StandardMailingView(views.APIView):
|
||||||
"""Exposes list and details of standard mailings (name and members) in
|
"""Exposes list and details of standard mailings (name and members) in
|
||||||
order to building the corresponding mailing lists.
|
order to building the corresponding mailing lists.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
pagination_class = PageSizedPagination
|
pagination_class = PageSizedPagination
|
||||||
permission_classes = (ACLPermission,)
|
permission_classes = (ACLPermission,)
|
||||||
perms_map = {'GET': [users.User.can_view_all]}
|
perms_map = {"GET": [users.User.can_view_all]}
|
||||||
|
|
||||||
def get(self, request, format=None):
|
def get(self, request, format=None):
|
||||||
adherents_data = serializers.MailingMemberSerializer(all_has_access(), many=True).data
|
adherents_data = serializers.MailingMemberSerializer(
|
||||||
data = [{'name': 'adherents', 'members': adherents_data}]
|
all_has_access(), many=True
|
||||||
|
).data
|
||||||
|
data = [{"name": "adherents", "members": adherents_data}]
|
||||||
paginator = self.pagination_class()
|
paginator = self.pagination_class()
|
||||||
paginator.paginate_queryset(data, request)
|
paginator.paginate_queryset(data, request)
|
||||||
return paginator.get_paginated_response(data)
|
return paginator.get_paginated_response(data)
|
||||||
|
@ -678,6 +769,7 @@ class ClubMailingView(generics.ListAPIView):
|
||||||
"""Exposes list and details of club mailings (name, members and admins) in
|
"""Exposes list and details of club mailings (name, members and admins) in
|
||||||
order to build the corresponding mailing lists.
|
order to build the corresponding mailing lists.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = users.Club.objects.all()
|
queryset = users.Club.objects.all()
|
||||||
serializer_class = serializers.MailingSerializer
|
serializer_class = serializers.MailingSerializer
|
||||||
|
|
||||||
|
@ -696,12 +788,10 @@ class ObtainExpiringAuthToken(ObtainAuthToken):
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
serializer = self.serializer_class(data=request.data)
|
serializer = self.serializer_class(data=request.data)
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
user = serializer.validated_data['user']
|
user = serializer.validated_data["user"]
|
||||||
token, created = Token.objects.get_or_create(user=user)
|
token, created = Token.objects.get_or_create(user=user)
|
||||||
|
|
||||||
token_duration = datetime.timedelta(
|
token_duration = datetime.timedelta(seconds=settings.API_TOKEN_DURATION)
|
||||||
seconds=settings.API_TOKEN_DURATION
|
|
||||||
)
|
|
||||||
utc_now = datetime.datetime.now(datetime.timezone.utc)
|
utc_now = datetime.datetime.now(datetime.timezone.utc)
|
||||||
if not created and token.created < utc_now - token_duration:
|
if not created and token.created < utc_now - token_duration:
|
||||||
token.delete()
|
token.delete()
|
||||||
|
@ -709,7 +799,6 @@ class ObtainExpiringAuthToken(ObtainAuthToken):
|
||||||
token.created = datetime.datetime.utcnow()
|
token.created = datetime.datetime.utcnow()
|
||||||
token.save()
|
token.save()
|
||||||
|
|
||||||
return Response({
|
return Response(
|
||||||
'token': token.key,
|
{"token": token.key, "expiration": token.created + token_duration}
|
||||||
'expiration': token.created + token_duration
|
)
|
||||||
})
|
|
||||||
|
|
|
@ -38,13 +38,12 @@ def can_view(user):
|
||||||
A couple (allowed, msg) where allowed is a boolean which is True if
|
A couple (allowed, msg) where allowed is a boolean which is True if
|
||||||
viewing is granted and msg is a message (can be None).
|
viewing is granted and msg is a message (can be None).
|
||||||
"""
|
"""
|
||||||
can = user.has_module_perms('cotisations')
|
can = user.has_module_perms("cotisations")
|
||||||
if can:
|
if can:
|
||||||
return can, None, ('cotisations',)
|
return can, None, ("cotisations",)
|
||||||
else:
|
else:
|
||||||
return (
|
return (
|
||||||
can,
|
can,
|
||||||
_("You don't have the right to view this application."),
|
_("You don't have the right to view this application."),
|
||||||
('cotisations',)
|
("cotisations",),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -35,42 +35,50 @@ from .models import CustomInvoice, CostEstimate
|
||||||
|
|
||||||
class FactureAdmin(VersionAdmin):
|
class FactureAdmin(VersionAdmin):
|
||||||
"""Class admin d'une facture, tous les champs"""
|
"""Class admin d'une facture, tous les champs"""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class CostEstimateAdmin(VersionAdmin):
|
class CostEstimateAdmin(VersionAdmin):
|
||||||
"""Admin class for cost estimates."""
|
"""Admin class for cost estimates."""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class CustomInvoiceAdmin(VersionAdmin):
|
class CustomInvoiceAdmin(VersionAdmin):
|
||||||
"""Admin class for custom invoices."""
|
"""Admin class for custom invoices."""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class VenteAdmin(VersionAdmin):
|
class VenteAdmin(VersionAdmin):
|
||||||
"""Class admin d'une vente, tous les champs (facture related)"""
|
"""Class admin d'une vente, tous les champs (facture related)"""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ArticleAdmin(VersionAdmin):
|
class ArticleAdmin(VersionAdmin):
|
||||||
"""Class admin d'un article en vente"""
|
"""Class admin d'un article en vente"""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class BanqueAdmin(VersionAdmin):
|
class BanqueAdmin(VersionAdmin):
|
||||||
"""Class admin de la liste des banques (facture related)"""
|
"""Class admin de la liste des banques (facture related)"""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class PaiementAdmin(VersionAdmin):
|
class PaiementAdmin(VersionAdmin):
|
||||||
"""Class admin d'un moyen de paiement (facture related"""
|
"""Class admin d'un moyen de paiement (facture related"""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class CotisationAdmin(VersionAdmin):
|
class CotisationAdmin(VersionAdmin):
|
||||||
"""Class admin d'une cotisation (date de debut et de fin),
|
"""Class admin d'une cotisation (date de debut et de fin),
|
||||||
Vente related"""
|
Vente related"""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -47,8 +47,13 @@ from django.shortcuts import get_object_or_404
|
||||||
from re2o.field_permissions import FieldPermissionFormMixin
|
from re2o.field_permissions import FieldPermissionFormMixin
|
||||||
from re2o.mixins import FormRevMixin
|
from re2o.mixins import FormRevMixin
|
||||||
from .models import (
|
from .models import (
|
||||||
Article, Paiement, Facture, Banque,
|
Article,
|
||||||
CustomInvoice, Vente, CostEstimate,
|
Paiement,
|
||||||
|
Facture,
|
||||||
|
Banque,
|
||||||
|
CustomInvoice,
|
||||||
|
Vente,
|
||||||
|
CostEstimate,
|
||||||
)
|
)
|
||||||
from .payment_methods import balance
|
from .payment_methods import balance
|
||||||
|
|
||||||
|
@ -59,31 +64,27 @@ class FactureForm(FieldPermissionFormMixin, FormRevMixin, ModelForm):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, *args, creation=False, **kwargs):
|
def __init__(self, *args, creation=False, **kwargs):
|
||||||
user = kwargs['user']
|
user = kwargs["user"]
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
super(FactureForm, self).__init__(*args, prefix=prefix, **kwargs)
|
super(FactureForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
self.fields['paiement'].empty_label = \
|
self.fields["paiement"].empty_label = _("Select a payment method")
|
||||||
_("Select a payment method")
|
self.fields["paiement"].queryset = Paiement.find_allowed_payments(user)
|
||||||
self.fields['paiement'].queryset = Paiement.find_allowed_payments(user)
|
|
||||||
if not creation:
|
if not creation:
|
||||||
self.fields['user'].label = _("Member")
|
self.fields["user"].label = _("Member")
|
||||||
self.fields['user'].empty_label = \
|
self.fields["user"].empty_label = _("Select the proprietary member")
|
||||||
_("Select the proprietary member")
|
self.fields["valid"].label = _("Validated invoice")
|
||||||
self.fields['valid'].label = _("Validated invoice")
|
|
||||||
else:
|
else:
|
||||||
self.fields = {'paiement': self.fields['paiement']}
|
self.fields = {"paiement": self.fields["paiement"]}
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Facture
|
model = Facture
|
||||||
fields = '__all__'
|
fields = "__all__"
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
cleaned_data = super(FactureForm, self).clean()
|
cleaned_data = super(FactureForm, self).clean()
|
||||||
paiement = cleaned_data.get('paiement')
|
paiement = cleaned_data.get("paiement")
|
||||||
if not paiement:
|
if not paiement:
|
||||||
raise forms.ValidationError(
|
raise forms.ValidationError(_("A payment method must be specified."))
|
||||||
_("A payment method must be specified.")
|
|
||||||
)
|
|
||||||
return cleaned_data
|
return cleaned_data
|
||||||
|
|
||||||
|
|
||||||
|
@ -92,32 +93,30 @@ class SelectArticleForm(FormRevMixin, Form):
|
||||||
Form used to select an article during the creation of an invoice for a
|
Form used to select an article during the creation of an invoice for a
|
||||||
member.
|
member.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
article = forms.ModelChoiceField(
|
article = forms.ModelChoiceField(
|
||||||
queryset=Article.objects.none(),
|
queryset=Article.objects.none(), label=_("Article"), required=True
|
||||||
label=_("Article"),
|
|
||||||
required=True
|
|
||||||
)
|
)
|
||||||
quantity = forms.IntegerField(
|
quantity = forms.IntegerField(
|
||||||
label=_("Quantity"),
|
label=_("Quantity"), validators=[MinValueValidator(1)], required=True
|
||||||
validators=[MinValueValidator(1)],
|
|
||||||
required=True
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
user = kwargs.pop('user')
|
user = kwargs.pop("user")
|
||||||
target_user = kwargs.pop('target_user', None)
|
target_user = kwargs.pop("target_user", None)
|
||||||
super(SelectArticleForm, self).__init__(*args, **kwargs)
|
super(SelectArticleForm, self).__init__(*args, **kwargs)
|
||||||
self.fields['article'].queryset = Article.find_allowed_articles(
|
self.fields["article"].queryset = Article.find_allowed_articles(
|
||||||
user, target_user)
|
user, target_user
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class DiscountForm(Form):
|
class DiscountForm(Form):
|
||||||
"""
|
"""
|
||||||
Form used in oder to create a discount on an invoice.
|
Form used in oder to create a discount on an invoice.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
is_relative = forms.BooleanField(
|
is_relative = forms.BooleanField(
|
||||||
label=_("Discount is on percentage."),
|
label=_("Discount is on percentage."), required=False
|
||||||
required=False,
|
|
||||||
)
|
)
|
||||||
discount = forms.DecimalField(
|
discount = forms.DecimalField(
|
||||||
label=_("Discount"),
|
label=_("Discount"),
|
||||||
|
@ -130,8 +129,8 @@ class DiscountForm(Form):
|
||||||
|
|
||||||
def apply_to_invoice(self, invoice):
|
def apply_to_invoice(self, invoice):
|
||||||
invoice_price = invoice.prix_total()
|
invoice_price = invoice.prix_total()
|
||||||
discount = self.cleaned_data['discount']
|
discount = self.cleaned_data["discount"]
|
||||||
is_relative = self.cleaned_data['is_relative']
|
is_relative = self.cleaned_data["is_relative"]
|
||||||
if is_relative:
|
if is_relative:
|
||||||
amount = discount / 100 * invoice_price
|
amount = discount / 100 * invoice_price
|
||||||
else:
|
else:
|
||||||
|
@ -139,44 +138,42 @@ class DiscountForm(Form):
|
||||||
if amount:
|
if amount:
|
||||||
name = _("{}% discount") if is_relative else _("{}€ discount")
|
name = _("{}% discount") if is_relative else _("{}€ discount")
|
||||||
name = name.format(discount)
|
name = name.format(discount)
|
||||||
Vente.objects.create(
|
Vente.objects.create(facture=invoice, name=name, prix=-amount, number=1)
|
||||||
facture=invoice,
|
|
||||||
name=name,
|
|
||||||
prix=-amount,
|
|
||||||
number=1
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class CustomInvoiceForm(FormRevMixin, ModelForm):
|
class CustomInvoiceForm(FormRevMixin, ModelForm):
|
||||||
"""
|
"""
|
||||||
Form used to create a custom invoice.
|
Form used to create a custom invoice.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = CustomInvoice
|
model = CustomInvoice
|
||||||
fields = '__all__'
|
fields = "__all__"
|
||||||
|
|
||||||
|
|
||||||
class CostEstimateForm(FormRevMixin, ModelForm):
|
class CostEstimateForm(FormRevMixin, ModelForm):
|
||||||
"""
|
"""
|
||||||
Form used to create a cost estimate.
|
Form used to create a cost estimate.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = CostEstimate
|
model = CostEstimate
|
||||||
exclude = ['paid', 'final_invoice']
|
exclude = ["paid", "final_invoice"]
|
||||||
|
|
||||||
|
|
||||||
class ArticleForm(FormRevMixin, ModelForm):
|
class ArticleForm(FormRevMixin, ModelForm):
|
||||||
"""
|
"""
|
||||||
Form used to create an article.
|
Form used to create an article.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Article
|
model = Article
|
||||||
fields = '__all__'
|
fields = "__all__"
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
super(ArticleForm, self).__init__(*args, prefix=prefix, **kwargs)
|
super(ArticleForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
self.fields['name'].label = _("Article name")
|
self.fields["name"].label = _("Article name")
|
||||||
|
|
||||||
|
|
||||||
class DelArticleForm(FormRevMixin, Form):
|
class DelArticleForm(FormRevMixin, Form):
|
||||||
|
@ -184,19 +181,20 @@ class DelArticleForm(FormRevMixin, Form):
|
||||||
Form used to delete one or more of the currently available articles.
|
Form used to delete one or more of the currently available articles.
|
||||||
The user must choose the one to delete by checking the boxes.
|
The user must choose the one to delete by checking the boxes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
articles = forms.ModelMultipleChoiceField(
|
articles = forms.ModelMultipleChoiceField(
|
||||||
queryset=Article.objects.none(),
|
queryset=Article.objects.none(),
|
||||||
label=_("Available articles"),
|
label=_("Available articles"),
|
||||||
widget=forms.CheckboxSelectMultiple
|
widget=forms.CheckboxSelectMultiple,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
instances = kwargs.pop('instances', None)
|
instances = kwargs.pop("instances", None)
|
||||||
super(DelArticleForm, self).__init__(*args, **kwargs)
|
super(DelArticleForm, self).__init__(*args, **kwargs)
|
||||||
if instances:
|
if instances:
|
||||||
self.fields['articles'].queryset = instances
|
self.fields["articles"].queryset = instances
|
||||||
else:
|
else:
|
||||||
self.fields['articles'].queryset = Article.objects.all()
|
self.fields["articles"].queryset = Article.objects.all()
|
||||||
|
|
||||||
|
|
||||||
# TODO : change Paiement to Payment
|
# TODO : change Paiement to Payment
|
||||||
|
@ -206,15 +204,16 @@ class PaiementForm(FormRevMixin, ModelForm):
|
||||||
The 'cheque' type is used to associate a specific behaviour requiring
|
The 'cheque' type is used to associate a specific behaviour requiring
|
||||||
a cheque number and a bank.
|
a cheque number and a bank.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Paiement
|
model = Paiement
|
||||||
# TODO : change moyen to method and type_paiement to payment_type
|
# TODO : change moyen to method and type_paiement to payment_type
|
||||||
fields = ['moyen', 'available_for_everyone']
|
fields = ["moyen", "available_for_everyone"]
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
super(PaiementForm, self).__init__(*args, prefix=prefix, **kwargs)
|
super(PaiementForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
self.fields['moyen'].label = _("Payment method name")
|
self.fields["moyen"].label = _("Payment method name")
|
||||||
|
|
||||||
|
|
||||||
# TODO : change paiement to payment
|
# TODO : change paiement to payment
|
||||||
|
@ -223,20 +222,21 @@ class DelPaiementForm(FormRevMixin, Form):
|
||||||
Form used to delete one or more payment methods.
|
Form used to delete one or more payment methods.
|
||||||
The user must choose the one to delete by checking the boxes.
|
The user must choose the one to delete by checking the boxes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# TODO : change paiement to payment
|
# TODO : change paiement to payment
|
||||||
paiements = forms.ModelMultipleChoiceField(
|
paiements = forms.ModelMultipleChoiceField(
|
||||||
queryset=Paiement.objects.none(),
|
queryset=Paiement.objects.none(),
|
||||||
label=_("Available payment methods"),
|
label=_("Available payment methods"),
|
||||||
widget=forms.CheckboxSelectMultiple
|
widget=forms.CheckboxSelectMultiple,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
instances = kwargs.pop('instances', None)
|
instances = kwargs.pop("instances", None)
|
||||||
super(DelPaiementForm, self).__init__(*args, **kwargs)
|
super(DelPaiementForm, self).__init__(*args, **kwargs)
|
||||||
if instances:
|
if instances:
|
||||||
self.fields['paiements'].queryset = instances
|
self.fields["paiements"].queryset = instances
|
||||||
else:
|
else:
|
||||||
self.fields['paiements'].queryset = Paiement.objects.all()
|
self.fields["paiements"].queryset = Paiement.objects.all()
|
||||||
|
|
||||||
|
|
||||||
# TODO : change banque to bank
|
# TODO : change banque to bank
|
||||||
|
@ -244,15 +244,16 @@ class BanqueForm(FormRevMixin, ModelForm):
|
||||||
"""
|
"""
|
||||||
Form used to create a bank.
|
Form used to create a bank.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
# TODO : change banque to bank
|
# TODO : change banque to bank
|
||||||
model = Banque
|
model = Banque
|
||||||
fields = ['name']
|
fields = ["name"]
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
super(BanqueForm, self).__init__(*args, prefix=prefix, **kwargs)
|
super(BanqueForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
self.fields['name'].label = _("Bank name")
|
self.fields["name"].label = _("Bank name")
|
||||||
|
|
||||||
|
|
||||||
# TODO : change banque to bank
|
# TODO : change banque to bank
|
||||||
|
@ -261,20 +262,21 @@ class DelBanqueForm(FormRevMixin, Form):
|
||||||
Form used to delete one or more banks.
|
Form used to delete one or more banks.
|
||||||
The use must choose the one to delete by checking the boxes.
|
The use must choose the one to delete by checking the boxes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# TODO : change banque to bank
|
# TODO : change banque to bank
|
||||||
banques = forms.ModelMultipleChoiceField(
|
banques = forms.ModelMultipleChoiceField(
|
||||||
queryset=Banque.objects.none(),
|
queryset=Banque.objects.none(),
|
||||||
label=_("Available banks"),
|
label=_("Available banks"),
|
||||||
widget=forms.CheckboxSelectMultiple
|
widget=forms.CheckboxSelectMultiple,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
instances = kwargs.pop('instances', None)
|
instances = kwargs.pop("instances", None)
|
||||||
super(DelBanqueForm, self).__init__(*args, **kwargs)
|
super(DelBanqueForm, self).__init__(*args, **kwargs)
|
||||||
if instances:
|
if instances:
|
||||||
self.fields['banques'].queryset = instances
|
self.fields["banques"].queryset = instances
|
||||||
else:
|
else:
|
||||||
self.fields['banques'].queryset = Banque.objects.all()
|
self.fields["banques"].queryset = Banque.objects.all()
|
||||||
|
|
||||||
|
|
||||||
# TODO : Better name and docstring
|
# TODO : Better name and docstring
|
||||||
|
@ -282,36 +284,36 @@ class RechargeForm(FormRevMixin, Form):
|
||||||
"""
|
"""
|
||||||
Form used to refill a user's balance
|
Form used to refill a user's balance
|
||||||
"""
|
"""
|
||||||
value = forms.DecimalField(
|
|
||||||
label=_("Amount"),
|
value = forms.DecimalField(label=_("Amount"), decimal_places=2)
|
||||||
decimal_places=2,
|
|
||||||
)
|
|
||||||
payment = forms.ModelChoiceField(
|
payment = forms.ModelChoiceField(
|
||||||
queryset=Paiement.objects.none(),
|
queryset=Paiement.objects.none(), label=_("Payment method")
|
||||||
label=_("Payment method")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, user=None, user_source=None, **kwargs):
|
def __init__(self, *args, user=None, user_source=None, **kwargs):
|
||||||
self.user = user
|
self.user = user
|
||||||
super(RechargeForm, self).__init__(*args, **kwargs)
|
super(RechargeForm, self).__init__(*args, **kwargs)
|
||||||
self.fields['payment'].empty_label = \
|
self.fields["payment"].empty_label = _("Select a payment method")
|
||||||
_("Select a payment method")
|
self.fields["payment"].queryset = Paiement.find_allowed_payments(
|
||||||
self.fields['payment'].queryset = Paiement.find_allowed_payments(
|
user_source
|
||||||
user_source).exclude(is_balance=True)
|
).exclude(is_balance=True)
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
"""
|
"""
|
||||||
Returns a cleaned value from the received form by validating
|
Returns a cleaned value from the received form by validating
|
||||||
the value is well inside the possible limits
|
the value is well inside the possible limits
|
||||||
"""
|
"""
|
||||||
value = self.cleaned_data['value']
|
value = self.cleaned_data["value"]
|
||||||
balance_method = get_object_or_404(balance.PaymentMethod)
|
balance_method = get_object_or_404(balance.PaymentMethod)
|
||||||
if balance_method.maximum_balance is not None and \
|
if (
|
||||||
value + self.user.solde > balance_method.maximum_balance:
|
balance_method.maximum_balance is not None
|
||||||
|
and value + self.user.solde > balance_method.maximum_balance
|
||||||
|
):
|
||||||
raise forms.ValidationError(
|
raise forms.ValidationError(
|
||||||
_("Requested amount is too high. Your balance can't exceed"
|
_(
|
||||||
" %(max_online_balance)s €.") % {
|
"Requested amount is too high. Your balance can't exceed"
|
||||||
'max_online_balance': balance_method.maximum_balance
|
" %(max_online_balance)s €."
|
||||||
}
|
)
|
||||||
|
% {"max_online_balance": balance_method.maximum_balance}
|
||||||
)
|
)
|
||||||
return self.cleaned_data
|
return self.cleaned_data
|
||||||
|
|
|
@ -29,54 +29,100 @@ import django.db.models.deletion
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("users", "0005_auto_20160702_0006")]
|
||||||
('users', '0005_auto_20160702_0006'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Article',
|
name="Article",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(verbose_name='ID', auto_created=True, primary_key=True, serialize=False)),
|
(
|
||||||
('name', models.CharField(max_length=255)),
|
"id",
|
||||||
('prix', models.DecimalField(decimal_places=2, max_digits=5)),
|
models.AutoField(
|
||||||
|
verbose_name="ID",
|
||||||
|
auto_created=True,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("name", models.CharField(max_length=255)),
|
||||||
|
("prix", models.DecimalField(decimal_places=2, max_digits=5)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Banque',
|
name="Banque",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(verbose_name='ID', auto_created=True, primary_key=True, serialize=False)),
|
(
|
||||||
('name', models.CharField(max_length=255)),
|
"id",
|
||||||
|
models.AutoField(
|
||||||
|
verbose_name="ID",
|
||||||
|
auto_created=True,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("name", models.CharField(max_length=255)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Facture',
|
name="Facture",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(verbose_name='ID', auto_created=True, primary_key=True, serialize=False)),
|
(
|
||||||
('cheque', models.CharField(max_length=255)),
|
"id",
|
||||||
('number', models.IntegerField()),
|
models.AutoField(
|
||||||
('date', models.DateTimeField(auto_now_add=True)),
|
verbose_name="ID",
|
||||||
('name', models.CharField(max_length=255)),
|
auto_created=True,
|
||||||
('prix', models.DecimalField(decimal_places=2, max_digits=5)),
|
primary_key=True,
|
||||||
('article', models.ForeignKey(to='cotisations.Article', on_delete=django.db.models.deletion.PROTECT)),
|
serialize=False,
|
||||||
('banque', models.ForeignKey(to='cotisations.Banque', on_delete=django.db.models.deletion.PROTECT)),
|
),
|
||||||
|
),
|
||||||
|
("cheque", models.CharField(max_length=255)),
|
||||||
|
("number", models.IntegerField()),
|
||||||
|
("date", models.DateTimeField(auto_now_add=True)),
|
||||||
|
("name", models.CharField(max_length=255)),
|
||||||
|
("prix", models.DecimalField(decimal_places=2, max_digits=5)),
|
||||||
|
(
|
||||||
|
"article",
|
||||||
|
models.ForeignKey(
|
||||||
|
to="cotisations.Article",
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"banque",
|
||||||
|
models.ForeignKey(
|
||||||
|
to="cotisations.Banque",
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Paiement',
|
name="Paiement",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(verbose_name='ID', auto_created=True, primary_key=True, serialize=False)),
|
(
|
||||||
('moyen', models.CharField(max_length=255)),
|
"id",
|
||||||
|
models.AutoField(
|
||||||
|
verbose_name="ID",
|
||||||
|
auto_created=True,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("moyen", models.CharField(max_length=255)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='paiement',
|
name="paiement",
|
||||||
field=models.ForeignKey(to='cotisations.Paiement', on_delete=django.db.models.deletion.PROTECT),
|
field=models.ForeignKey(
|
||||||
|
to="cotisations.Paiement", on_delete=django.db.models.deletion.PROTECT
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='user',
|
name="user",
|
||||||
field=models.ForeignKey(to='users.User', on_delete=django.db.models.deletion.PROTECT),
|
field=models.ForeignKey(
|
||||||
|
to="users.User", on_delete=django.db.models.deletion.PROTECT
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -28,13 +28,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0001_initial")]
|
||||||
('cotisations', '0001_initial'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [migrations.RemoveField(model_name="facture", name="article")]
|
||||||
migrations.RemoveField(
|
|
||||||
model_name='facture',
|
|
||||||
name='article',
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
|
@ -29,14 +29,17 @@ import django.db.models.deletion
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0002_remove_facture_article")]
|
||||||
('cotisations', '0002_remove_facture_article'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='banque',
|
name="banque",
|
||||||
field=models.ForeignKey(blank=True, to='cotisations.Banque', on_delete=django.db.models.deletion.PROTECT, null=True),
|
field=models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
to="cotisations.Banque",
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
null=True,
|
||||||
),
|
),
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -28,19 +28,17 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0003_auto_20160702_1448")]
|
||||||
('cotisations', '0003_auto_20160702_1448'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='name',
|
name="name",
|
||||||
field=models.CharField(null=True, max_length=255),
|
field=models.CharField(null=True, max_length=255),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='prix',
|
name="prix",
|
||||||
field=models.DecimalField(max_digits=5, null=True, decimal_places=2),
|
field=models.DecimalField(max_digits=5, null=True, decimal_places=2),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -28,14 +28,12 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0004_auto_20160702_1528")]
|
||||||
('cotisations', '0004_auto_20160702_1528'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='cheque',
|
name="cheque",
|
||||||
field=models.CharField(max_length=255, blank=True),
|
field=models.CharField(max_length=255, blank=True),
|
||||||
),
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -28,19 +28,19 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0005_auto_20160702_1532")]
|
||||||
('cotisations', '0005_auto_20160702_1532'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='name',
|
name="name",
|
||||||
field=models.CharField(null=True, default='plop', max_length=255),
|
field=models.CharField(null=True, default="plop", max_length=255),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='prix',
|
name="prix",
|
||||||
field=models.DecimalField(null=True, decimal_places=2, default=1, max_digits=5),
|
field=models.DecimalField(
|
||||||
|
null=True, decimal_places=2, default=1, max_digits=5
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -28,20 +28,18 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0006_auto_20160702_1534")]
|
||||||
('cotisations', '0006_auto_20160702_1534'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='name',
|
name="name",
|
||||||
field=models.CharField(default='plop', max_length=255),
|
field=models.CharField(default="plop", max_length=255),
|
||||||
preserve_default=False,
|
preserve_default=False,
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='prix',
|
name="prix",
|
||||||
field=models.DecimalField(default=1, max_digits=5, decimal_places=2),
|
field=models.DecimalField(default=1, max_digits=5, decimal_places=2),
|
||||||
preserve_default=False,
|
preserve_default=False,
|
||||||
),
|
),
|
||||||
|
|
|
@ -30,43 +30,53 @@ import django.db.models.deletion
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('users', '0005_auto_20160702_0006'),
|
("users", "0005_auto_20160702_0006"),
|
||||||
('cotisations', '0007_auto_20160702_1543'),
|
("cotisations", "0007_auto_20160702_1543"),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Cotisation',
|
name="Cotisation",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(verbose_name='ID', primary_key=True, serialize=False, auto_created=True)),
|
(
|
||||||
('date_start', models.DateTimeField(auto_now_add=True)),
|
"id",
|
||||||
('date_end', models.DateTimeField()),
|
models.AutoField(
|
||||||
|
verbose_name="ID",
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
auto_created=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("date_start", models.DateTimeField(auto_now_add=True)),
|
||||||
|
("date_end", models.DateTimeField()),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='cotisation',
|
name="cotisation",
|
||||||
field=models.BooleanField(default=True),
|
field=models.BooleanField(default=True),
|
||||||
preserve_default=False,
|
preserve_default=False,
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='duration',
|
name="duration",
|
||||||
field=models.DurationField(blank=True, null=True),
|
field=models.DurationField(blank=True, null=True),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='facture',
|
model_name="facture", name="valid", field=models.BooleanField(default=True)
|
||||||
name='valid',
|
|
||||||
field=models.BooleanField(default=True),
|
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='cotisation',
|
model_name="cotisation",
|
||||||
name='facture',
|
name="facture",
|
||||||
field=models.ForeignKey(to='cotisations.Facture', on_delete=django.db.models.deletion.PROTECT),
|
field=models.ForeignKey(
|
||||||
|
to="cotisations.Facture", on_delete=django.db.models.deletion.PROTECT
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='cotisation',
|
model_name="cotisation",
|
||||||
name='user',
|
name="user",
|
||||||
field=models.ForeignKey(to='users.User', on_delete=django.db.models.deletion.PROTECT),
|
field=models.ForeignKey(
|
||||||
|
to="users.User", on_delete=django.db.models.deletion.PROTECT
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -28,13 +28,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0008_auto_20160702_1614")]
|
||||||
('cotisations', '0008_auto_20160702_1614'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [migrations.RemoveField(model_name="cotisation", name="user")]
|
||||||
migrations.RemoveField(
|
|
||||||
model_name='cotisation',
|
|
||||||
name='user',
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
|
@ -28,18 +28,15 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0009_remove_cotisation_user")]
|
||||||
('cotisations', '0009_remove_cotisation_user'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.RemoveField(
|
migrations.RemoveField(model_name="article", name="duration"),
|
||||||
model_name='article',
|
|
||||||
name='duration',
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='duration',
|
name="duration",
|
||||||
field=models.IntegerField(null=True, help_text='Durée exprimée en mois entiers', blank=True),
|
field=models.IntegerField(
|
||||||
|
null=True, help_text="Durée exprimée en mois entiers", blank=True
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -28,14 +28,10 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0010_auto_20160702_1840")]
|
||||||
('cotisations', '0010_auto_20160702_1840'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='cotisation',
|
model_name="cotisation", name="date_start", field=models.DateTimeField()
|
||||||
name='date_start',
|
)
|
||||||
field=models.DateTimeField(),
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -29,14 +29,14 @@ import django.db.models.deletion
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0011_auto_20160702_1911")]
|
||||||
('cotisations', '0011_auto_20160702_1911'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='cotisation',
|
model_name="cotisation",
|
||||||
name='facture',
|
name="facture",
|
||||||
field=models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='cotisations.Facture'),
|
field=models.OneToOneField(
|
||||||
|
on_delete=django.db.models.deletion.PROTECT, to="cotisations.Facture"
|
||||||
),
|
),
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -29,32 +29,41 @@ import django.db.models.deletion
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0012_auto_20160704_0118")]
|
||||||
('cotisations', '0012_auto_20160704_0118'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Vente',
|
name="Vente",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
(
|
||||||
('name', models.CharField(max_length=255)),
|
"id",
|
||||||
('prix', models.DecimalField(decimal_places=2, max_digits=5)),
|
models.AutoField(
|
||||||
('cotisation', models.BooleanField()),
|
auto_created=True,
|
||||||
('duration', models.IntegerField(null=True, blank=True, help_text='Durée exprimée en mois entiers')),
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
verbose_name="ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("name", models.CharField(max_length=255)),
|
||||||
|
("prix", models.DecimalField(decimal_places=2, max_digits=5)),
|
||||||
|
("cotisation", models.BooleanField()),
|
||||||
|
(
|
||||||
|
"duration",
|
||||||
|
models.IntegerField(
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
help_text="Durée exprimée en mois entiers",
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
migrations.RemoveField(
|
migrations.RemoveField(model_name="facture", name="name"),
|
||||||
model_name='facture',
|
migrations.RemoveField(model_name="facture", name="prix"),
|
||||||
name='name',
|
|
||||||
),
|
|
||||||
migrations.RemoveField(
|
|
||||||
model_name='facture',
|
|
||||||
name='prix',
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='facture',
|
name="facture",
|
||||||
field=models.ForeignKey(to='cotisations.Facture', on_delete=django.db.models.deletion.PROTECT),
|
field=models.ForeignKey(
|
||||||
|
to="cotisations.Facture", on_delete=django.db.models.deletion.PROTECT
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -28,18 +28,13 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0013_auto_20160711_2240")]
|
||||||
('cotisations', '0013_auto_20160711_2240'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.RemoveField(
|
migrations.RemoveField(model_name="facture", name="number"),
|
||||||
model_name='facture',
|
|
||||||
name='number',
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='number',
|
name="number",
|
||||||
field=models.IntegerField(default=1),
|
field=models.IntegerField(default=1),
|
||||||
preserve_default=False,
|
preserve_default=False,
|
||||||
),
|
),
|
||||||
|
|
|
@ -29,29 +29,29 @@ import django.core.validators
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0014_auto_20160712_0245")]
|
||||||
('cotisations', '0014_auto_20160712_0245'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='control',
|
name="control",
|
||||||
field=models.BooleanField(default=False),
|
field=models.BooleanField(default=False),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='cotisation',
|
model_name="cotisation",
|
||||||
name='facture',
|
name="facture",
|
||||||
field=models.OneToOneField(to='cotisations.Facture'),
|
field=models.OneToOneField(to="cotisations.Facture"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='facture',
|
name="facture",
|
||||||
field=models.ForeignKey(to='cotisations.Facture'),
|
field=models.ForeignKey(to="cotisations.Facture"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='number',
|
name="number",
|
||||||
field=models.IntegerField(validators=[django.core.validators.MinValueValidator(1)]),
|
field=models.IntegerField(
|
||||||
|
validators=[django.core.validators.MinValueValidator(1)]
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -28,29 +28,20 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0015_auto_20160714_2142")]
|
||||||
('cotisations', '0015_auto_20160714_2142'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.RenameField(
|
migrations.RenameField(
|
||||||
model_name='article',
|
model_name="article", old_name="cotisation", new_name="iscotisation"
|
||||||
old_name='cotisation',
|
|
||||||
new_name='iscotisation',
|
|
||||||
),
|
),
|
||||||
migrations.RenameField(
|
migrations.RenameField(
|
||||||
model_name='vente',
|
model_name="vente", old_name="cotisation", new_name="iscotisation"
|
||||||
old_name='cotisation',
|
|
||||||
new_name='iscotisation',
|
|
||||||
),
|
|
||||||
migrations.RemoveField(
|
|
||||||
model_name='cotisation',
|
|
||||||
name='facture',
|
|
||||||
),
|
),
|
||||||
|
migrations.RemoveField(model_name="cotisation", name="facture"),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='cotisation',
|
model_name="cotisation",
|
||||||
name='vente',
|
name="vente",
|
||||||
field=models.OneToOneField(to='cotisations.Vente', null=True),
|
field=models.OneToOneField(to="cotisations.Vente", null=True),
|
||||||
preserve_default=False,
|
preserve_default=False,
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -8,19 +8,22 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0016_auto_20160715_0110")]
|
||||||
('cotisations', '0016_auto_20160715_0110'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='duration',
|
name="duration",
|
||||||
field=models.IntegerField(blank=True, help_text='Durée exprimée en mois entiers', null=True, validators=[django.core.validators.MinValueValidator(0)]),
|
field=models.IntegerField(
|
||||||
|
blank=True,
|
||||||
|
help_text="Durée exprimée en mois entiers",
|
||||||
|
null=True,
|
||||||
|
validators=[django.core.validators.MinValueValidator(0)],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='name',
|
name="name",
|
||||||
field=models.CharField(max_length=255, unique=True),
|
field=models.CharField(max_length=255, unique=True),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,15 +7,17 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0017_auto_20170718_2329")]
|
||||||
('cotisations', '0017_auto_20170718_2329'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='paiement',
|
model_name="paiement",
|
||||||
name='type_paiement',
|
name="type_paiement",
|
||||||
field=models.CharField(choices=[('check', 'Chèque'), (None, 'Autre')], default=None, max_length=255),
|
field=models.CharField(
|
||||||
preserve_default=False,
|
choices=[("check", "Chèque"), (None, "Autre")],
|
||||||
|
default=None,
|
||||||
|
max_length=255,
|
||||||
),
|
),
|
||||||
|
preserve_default=False,
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,14 +7,14 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0018_paiement_type_paiement")]
|
||||||
('cotisations', '0018_paiement_type_paiement'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='paiement',
|
model_name="paiement",
|
||||||
name='type_paiement',
|
name="type_paiement",
|
||||||
field=models.CharField(choices=[(0, 'Autre'), (1, 'Chèque')], default=0, max_length=255),
|
field=models.CharField(
|
||||||
|
choices=[(0, "Autre"), (1, "Chèque")], default=0, max_length=255
|
||||||
),
|
),
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,14 +7,14 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0019_auto_20170819_0055")]
|
||||||
('cotisations', '0019_auto_20170819_0055'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='paiement',
|
model_name="paiement",
|
||||||
name='type_paiement',
|
name="type_paiement",
|
||||||
field=models.IntegerField(choices=[(0, 'Autre'), (1, 'Chèque')], default=0, max_length=255),
|
field=models.IntegerField(
|
||||||
|
choices=[(0, "Autre"), (1, "Chèque")], default=0, max_length=255
|
||||||
),
|
),
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,14 +7,12 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0020_auto_20170819_0057")]
|
||||||
('cotisations', '0020_auto_20170819_0057'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='paiement',
|
model_name="paiement",
|
||||||
name='type_paiement',
|
name="type_paiement",
|
||||||
field=models.IntegerField(choices=[(0, 'Autre'), (1, 'Chèque')], default=0),
|
field=models.IntegerField(choices=[(0, "Autre"), (1, "Chèque")], default=0),
|
||||||
),
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,14 +7,14 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0021_auto_20170819_0104")]
|
||||||
('cotisations', '0021_auto_20170819_0104'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='paiement',
|
model_name="paiement",
|
||||||
name='type_paiement',
|
name="type_paiement",
|
||||||
field=models.IntegerField(choices=[(0, 'Autre'), (1, 'Chèque')], default=0, max_length=255),
|
field=models.IntegerField(
|
||||||
|
choices=[(0, "Autre"), (1, "Chèque")], default=0, max_length=255
|
||||||
),
|
),
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,14 +7,12 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0022_auto_20170824_0128")]
|
||||||
('cotisations', '0022_auto_20170824_0128'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='paiement',
|
model_name="paiement",
|
||||||
name='type_paiement',
|
name="type_paiement",
|
||||||
field=models.IntegerField(choices=[(0, 'Autre'), (1, 'Chèque')], default=0),
|
field=models.IntegerField(choices=[(0, "Autre"), (1, "Chèque")], default=0),
|
||||||
),
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -8,19 +8,24 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0023_auto_20170902_1303")]
|
||||||
('cotisations', '0023_auto_20170902_1303'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='duration',
|
name="duration",
|
||||||
field=models.PositiveIntegerField(blank=True, help_text='Durée exprimée en mois entiers', null=True, validators=[django.core.validators.MinValueValidator(0)]),
|
field=models.PositiveIntegerField(
|
||||||
|
blank=True,
|
||||||
|
help_text="Durée exprimée en mois entiers",
|
||||||
|
null=True,
|
||||||
|
validators=[django.core.validators.MinValueValidator(0)],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='duration',
|
name="duration",
|
||||||
field=models.PositiveIntegerField(blank=True, help_text='Durée exprimée en mois entiers', null=True),
|
field=models.PositiveIntegerField(
|
||||||
|
blank=True, help_text="Durée exprimée en mois entiers", null=True
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,14 +7,16 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0024_auto_20171015_2033")]
|
||||||
('cotisations', '0024_auto_20171015_2033'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='type_user',
|
name="type_user",
|
||||||
field=models.CharField(choices=[('Adherent', 'Adherent'), ('Club', 'Club'), ('All', 'All')], default='All', max_length=255),
|
field=models.CharField(
|
||||||
|
choices=[("Adherent", "Adherent"), ("Club", "Club"), ("All", "All")],
|
||||||
|
default="All",
|
||||||
|
max_length=255,
|
||||||
),
|
),
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -6,28 +6,29 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
def create_type(apps, schema_editor):
|
def create_type(apps, schema_editor):
|
||||||
Cotisation = apps.get_model('cotisations', 'Cotisation')
|
Cotisation = apps.get_model("cotisations", "Cotisation")
|
||||||
Vente = apps.get_model('cotisations', 'Vente')
|
Vente = apps.get_model("cotisations", "Vente")
|
||||||
Article = apps.get_model('cotisations', 'Article')
|
Article = apps.get_model("cotisations", "Article")
|
||||||
db_alias = schema_editor.connection.alias
|
db_alias = schema_editor.connection.alias
|
||||||
articles = Article.objects.using(db_alias).all()
|
articles = Article.objects.using(db_alias).all()
|
||||||
ventes = Vente.objects.using(db_alias).all()
|
ventes = Vente.objects.using(db_alias).all()
|
||||||
cotisations = Cotisation.objects.using(db_alias).all()
|
cotisations = Cotisation.objects.using(db_alias).all()
|
||||||
for article in articles:
|
for article in articles:
|
||||||
if article.iscotisation:
|
if article.iscotisation:
|
||||||
article.type_cotisation='All'
|
article.type_cotisation = "All"
|
||||||
article.save(using=db_alias)
|
article.save(using=db_alias)
|
||||||
for vente in ventes:
|
for vente in ventes:
|
||||||
if vente.iscotisation:
|
if vente.iscotisation:
|
||||||
vente.type_cotisation='All'
|
vente.type_cotisation = "All"
|
||||||
vente.save(using=db_alias)
|
vente.save(using=db_alias)
|
||||||
for cotisation in cotisations:
|
for cotisation in cotisations:
|
||||||
cotisation.type_cotisation='All'
|
cotisation.type_cotisation = "All"
|
||||||
cotisation.save(using=db_alias)
|
cotisation.save(using=db_alias)
|
||||||
|
|
||||||
|
|
||||||
def delete_type(apps, schema_editor):
|
def delete_type(apps, schema_editor):
|
||||||
Vente = apps.get_model('cotisations', 'Vente')
|
Vente = apps.get_model("cotisations", "Vente")
|
||||||
Article = apps.get_model('cotisations', 'Article')
|
Article = apps.get_model("cotisations", "Article")
|
||||||
db_alias = schema_editor.connection.alias
|
db_alias = schema_editor.connection.alias
|
||||||
articles = Article.objects.using(db_alias).all()
|
articles = Article.objects.using(db_alias).all()
|
||||||
ventes = Vente.objects.using(db_alias).all()
|
ventes = Vente.objects.using(db_alias).all()
|
||||||
|
@ -44,35 +45,55 @@ def delete_type(apps, schema_editor):
|
||||||
vente.iscotisation = False
|
vente.iscotisation = False
|
||||||
vente.save(using=db_alias)
|
vente.save(using=db_alias)
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0025_article_type_user")]
|
||||||
('cotisations', '0025_article_type_user'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='type_cotisation',
|
name="type_cotisation",
|
||||||
field=models.CharField(blank=True, choices=[('Connexion', 'Connexion'), ('Adhesion', 'Adhesion'), ('All', 'All')], default=None, max_length=255, null=True),
|
field=models.CharField(
|
||||||
|
blank=True,
|
||||||
|
choices=[
|
||||||
|
("Connexion", "Connexion"),
|
||||||
|
("Adhesion", "Adhesion"),
|
||||||
|
("All", "All"),
|
||||||
|
],
|
||||||
|
default=None,
|
||||||
|
max_length=255,
|
||||||
|
null=True,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='cotisation',
|
model_name="cotisation",
|
||||||
name='type_cotisation',
|
name="type_cotisation",
|
||||||
field=models.CharField(choices=[('Connexion', 'Connexion'), ('Adhesion', 'Adhesion'), ('All', 'All')], max_length=255, default='All'),
|
field=models.CharField(
|
||||||
|
choices=[
|
||||||
|
("Connexion", "Connexion"),
|
||||||
|
("Adhesion", "Adhesion"),
|
||||||
|
("All", "All"),
|
||||||
|
],
|
||||||
|
max_length=255,
|
||||||
|
default="All",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='type_cotisation',
|
name="type_cotisation",
|
||||||
field=models.CharField(blank=True, choices=[('Connexion', 'Connexion'), ('Adhesion', 'Adhesion'), ('All', 'All')], max_length=255, null=True),
|
field=models.CharField(
|
||||||
|
blank=True,
|
||||||
|
choices=[
|
||||||
|
("Connexion", "Connexion"),
|
||||||
|
("Adhesion", "Adhesion"),
|
||||||
|
("All", "All"),
|
||||||
|
],
|
||||||
|
max_length=255,
|
||||||
|
null=True,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.RunPython(create_type, delete_type),
|
migrations.RunPython(create_type, delete_type),
|
||||||
migrations.RemoveField(
|
migrations.RemoveField(model_name="article", name="iscotisation"),
|
||||||
model_name='article',
|
migrations.RemoveField(model_name="vente", name="iscotisation"),
|
||||||
name='iscotisation',
|
|
||||||
),
|
|
||||||
migrations.RemoveField(
|
|
||||||
model_name='vente',
|
|
||||||
name='iscotisation',
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,14 +7,10 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0026_auto_20171028_0126")]
|
||||||
('cotisations', '0026_auto_20171028_0126'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name="article", name="name", field=models.CharField(max_length=255)
|
||||||
name='name',
|
)
|
||||||
field=models.CharField(max_length=255),
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,33 +7,56 @@ from django.db import migrations
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0027_auto_20171029_1156")]
|
||||||
('cotisations', '0027_auto_20171029_1156'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='article',
|
name="article",
|
||||||
options={'permissions': (('view_article', 'Peut voir un objet article'),)},
|
options={"permissions": (("view_article", "Peut voir un objet article"),)},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='banque',
|
name="banque",
|
||||||
options={'permissions': (('view_banque', 'Peut voir un objet banque'),)},
|
options={"permissions": (("view_banque", "Peut voir un objet banque"),)},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='cotisation',
|
name="cotisation",
|
||||||
options={'permissions': (('view_cotisation', 'Peut voir un objet cotisation'), ('change_all_cotisation', 'Superdroit, peut modifier toutes les cotisations'))},
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("view_cotisation", "Peut voir un objet cotisation"),
|
||||||
|
(
|
||||||
|
"change_all_cotisation",
|
||||||
|
"Superdroit, peut modifier toutes les cotisations",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='facture',
|
name="facture",
|
||||||
options={'permissions': (('change_facture_control', "Peut changer l'etat de controle"), ('change_facture_pdf', 'Peut éditer une facture pdf'), ('view_facture', 'Peut voir un objet facture'), ('change_all_facture', 'Superdroit, peut modifier toutes les factures'))},
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("change_facture_control", "Peut changer l'etat de controle"),
|
||||||
|
("change_facture_pdf", "Peut éditer une facture pdf"),
|
||||||
|
("view_facture", "Peut voir un objet facture"),
|
||||||
|
(
|
||||||
|
"change_all_facture",
|
||||||
|
"Superdroit, peut modifier toutes les factures",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='paiement',
|
name="paiement",
|
||||||
options={'permissions': (('view_paiement', 'Peut voir un objet paiement'),)},
|
options={
|
||||||
|
"permissions": (("view_paiement", "Peut voir un objet paiement"),)
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='vente',
|
name="vente",
|
||||||
options={'permissions': (('view_vente', 'Peut voir un objet vente'), ('change_all_vente', 'Superdroit, peut modifier toutes les ventes'))},
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("view_vente", "Peut voir un objet vente"),
|
||||||
|
("change_all_vente", "Superdroit, peut modifier toutes les ventes"),
|
||||||
|
)
|
||||||
|
},
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -9,143 +9,242 @@ import django.db.models.deletion
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0028_auto_20171231_0007")]
|
||||||
('cotisations', '0028_auto_20171231_0007'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='article',
|
name="article",
|
||||||
options={'permissions': (('view_article', "Can see an article's details"),), 'verbose_name': 'Article', 'verbose_name_plural': 'Articles'},
|
options={
|
||||||
|
"permissions": (("view_article", "Can see an article's details"),),
|
||||||
|
"verbose_name": "Article",
|
||||||
|
"verbose_name_plural": "Articles",
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='banque',
|
name="banque",
|
||||||
options={'permissions': (('view_banque', "Can see a bank's details"),), 'verbose_name': 'Bank', 'verbose_name_plural': 'Banks'},
|
options={
|
||||||
|
"permissions": (("view_banque", "Can see a bank's details"),),
|
||||||
|
"verbose_name": "Bank",
|
||||||
|
"verbose_name_plural": "Banks",
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='cotisation',
|
name="cotisation",
|
||||||
options={'permissions': (('view_cotisation', "Can see a cotisation's details"), ('change_all_cotisation', 'Can edit the previous cotisations'))},
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("view_cotisation", "Can see a cotisation's details"),
|
||||||
|
("change_all_cotisation", "Can edit the previous cotisations"),
|
||||||
|
)
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='facture',
|
name="facture",
|
||||||
options={'permissions': (('change_facture_control', 'Can change the "controlled" state'), ('change_facture_pdf', 'Can create a custom PDF invoice'), ('view_facture', "Can see an invoice's details"), ('change_all_facture', 'Can edit all the previous invoices')), 'verbose_name': 'Invoice', 'verbose_name_plural': 'Invoices'},
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("change_facture_control", 'Can change the "controlled" state'),
|
||||||
|
("change_facture_pdf", "Can create a custom PDF invoice"),
|
||||||
|
("view_facture", "Can see an invoice's details"),
|
||||||
|
("change_all_facture", "Can edit all the previous invoices"),
|
||||||
|
),
|
||||||
|
"verbose_name": "Invoice",
|
||||||
|
"verbose_name_plural": "Invoices",
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='paiement',
|
name="paiement",
|
||||||
options={'permissions': (('view_paiement', "Can see a payement's details"),), 'verbose_name': 'Payment method', 'verbose_name_plural': 'Payment methods'},
|
options={
|
||||||
|
"permissions": (("view_paiement", "Can see a payement's details"),),
|
||||||
|
"verbose_name": "Payment method",
|
||||||
|
"verbose_name_plural": "Payment methods",
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='vente',
|
name="vente",
|
||||||
options={'permissions': (('view_vente', "Can see a purchase's details"), ('change_all_vente', 'Can edit all the previous purchases')), 'verbose_name': 'Purchase', 'verbose_name_plural': 'Purchases'},
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("view_vente", "Can see a purchase's details"),
|
||||||
|
("change_all_vente", "Can edit all the previous purchases"),
|
||||||
|
),
|
||||||
|
"verbose_name": "Purchase",
|
||||||
|
"verbose_name_plural": "Purchases",
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='duration',
|
name="duration",
|
||||||
field=models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Duration (in whole month)'),
|
field=models.PositiveIntegerField(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
validators=[django.core.validators.MinValueValidator(0)],
|
||||||
|
verbose_name="Duration (in whole month)",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='name',
|
name="name",
|
||||||
field=models.CharField(max_length=255, verbose_name='Designation'),
|
field=models.CharField(max_length=255, verbose_name="Designation"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='prix',
|
name="prix",
|
||||||
field=models.DecimalField(decimal_places=2, max_digits=5, verbose_name='Unitary price'),
|
field=models.DecimalField(
|
||||||
|
decimal_places=2, max_digits=5, verbose_name="Unitary price"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='type_cotisation',
|
name="type_cotisation",
|
||||||
field=models.CharField(blank=True, choices=[('Connexion', 'Connexion'), ('Adhesion', 'Membership'), ('All', 'Both of them')], default=None, max_length=255, null=True, verbose_name='Type of cotisation'),
|
field=models.CharField(
|
||||||
|
blank=True,
|
||||||
|
choices=[
|
||||||
|
("Connexion", "Connexion"),
|
||||||
|
("Adhesion", "Membership"),
|
||||||
|
("All", "Both of them"),
|
||||||
|
],
|
||||||
|
default=None,
|
||||||
|
max_length=255,
|
||||||
|
null=True,
|
||||||
|
verbose_name="Type of cotisation",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='type_user',
|
name="type_user",
|
||||||
field=models.CharField(choices=[('Adherent', 'Member'), ('Club', 'Club'), ('All', 'Both of them')], default='All', max_length=255, verbose_name='Type of users concerned'),
|
field=models.CharField(
|
||||||
|
choices=[
|
||||||
|
("Adherent", "Member"),
|
||||||
|
("Club", "Club"),
|
||||||
|
("All", "Both of them"),
|
||||||
|
],
|
||||||
|
default="All",
|
||||||
|
max_length=255,
|
||||||
|
verbose_name="Type of users concerned",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='banque',
|
model_name="banque",
|
||||||
name='name',
|
name="name",
|
||||||
field=models.CharField(max_length=255, verbose_name='Name'),
|
field=models.CharField(max_length=255, verbose_name="Name"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='cotisation',
|
model_name="cotisation",
|
||||||
name='date_end',
|
name="date_end",
|
||||||
field=models.DateTimeField(verbose_name='Ending date'),
|
field=models.DateTimeField(verbose_name="Ending date"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='cotisation',
|
model_name="cotisation",
|
||||||
name='date_start',
|
name="date_start",
|
||||||
field=models.DateTimeField(verbose_name='Starting date'),
|
field=models.DateTimeField(verbose_name="Starting date"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='cotisation',
|
model_name="cotisation",
|
||||||
name='type_cotisation',
|
name="type_cotisation",
|
||||||
field=models.CharField(choices=[('Connexion', 'Connexion'), ('Adhesion', 'Membership'), ('All', 'Both of them')], default='All', max_length=255, verbose_name='Type of cotisation'),
|
field=models.CharField(
|
||||||
|
choices=[
|
||||||
|
("Connexion", "Connexion"),
|
||||||
|
("Adhesion", "Membership"),
|
||||||
|
("All", "Both of them"),
|
||||||
|
],
|
||||||
|
default="All",
|
||||||
|
max_length=255,
|
||||||
|
verbose_name="Type of cotisation",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='cotisation',
|
model_name="cotisation",
|
||||||
name='vente',
|
name="vente",
|
||||||
field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to='cotisations.Vente', verbose_name='Purchase'),
|
field=models.OneToOneField(
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
to="cotisations.Vente",
|
||||||
|
verbose_name="Purchase",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='cheque',
|
name="cheque",
|
||||||
field=models.CharField(blank=True, max_length=255, verbose_name='Cheque number'),
|
field=models.CharField(
|
||||||
|
blank=True, max_length=255, verbose_name="Cheque number"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='control',
|
name="control",
|
||||||
field=models.BooleanField(default=False, verbose_name='Controlled'),
|
field=models.BooleanField(default=False, verbose_name="Controlled"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='date',
|
name="date",
|
||||||
field=models.DateTimeField(auto_now_add=True, verbose_name='Date'),
|
field=models.DateTimeField(auto_now_add=True, verbose_name="Date"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='valid',
|
name="valid",
|
||||||
field=models.BooleanField(default=True, verbose_name='Validated'),
|
field=models.BooleanField(default=True, verbose_name="Validated"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='paiement',
|
model_name="paiement",
|
||||||
name='moyen',
|
name="moyen",
|
||||||
field=models.CharField(max_length=255, verbose_name='Method'),
|
field=models.CharField(max_length=255, verbose_name="Method"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='paiement',
|
model_name="paiement",
|
||||||
name='type_paiement',
|
name="type_paiement",
|
||||||
field=models.IntegerField(choices=[(0, 'Standard'), (1, 'Cheque')], default=0, verbose_name='Payment type'),
|
field=models.IntegerField(
|
||||||
|
choices=[(0, "Standard"), (1, "Cheque")],
|
||||||
|
default=0,
|
||||||
|
verbose_name="Payment type",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='duration',
|
name="duration",
|
||||||
field=models.PositiveIntegerField(blank=True, null=True, verbose_name='Duration (in whole month)'),
|
field=models.PositiveIntegerField(
|
||||||
|
blank=True, null=True, verbose_name="Duration (in whole month)"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='facture',
|
name="facture",
|
||||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cotisations.Facture', verbose_name='Invoice'),
|
field=models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
to="cotisations.Facture",
|
||||||
|
verbose_name="Invoice",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='name',
|
name="name",
|
||||||
field=models.CharField(max_length=255, verbose_name='Article'),
|
field=models.CharField(max_length=255, verbose_name="Article"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='number',
|
name="number",
|
||||||
field=models.IntegerField(validators=[django.core.validators.MinValueValidator(1)], verbose_name='Amount'),
|
field=models.IntegerField(
|
||||||
|
validators=[django.core.validators.MinValueValidator(1)],
|
||||||
|
verbose_name="Amount",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='prix',
|
name="prix",
|
||||||
field=models.DecimalField(decimal_places=2, max_digits=5, verbose_name='Price'),
|
field=models.DecimalField(
|
||||||
|
decimal_places=2, max_digits=5, verbose_name="Price"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='type_cotisation',
|
name="type_cotisation",
|
||||||
field=models.CharField(blank=True, choices=[('Connexion', 'Connexion'), ('Adhesion', 'Membership'), ('All', 'Both of them')], max_length=255, null=True, verbose_name='Type of cotisation'),
|
field=models.CharField(
|
||||||
|
blank=True,
|
||||||
|
choices=[
|
||||||
|
("Connexion", "Connexion"),
|
||||||
|
("Adhesion", "Membership"),
|
||||||
|
("All", "Both of them"),
|
||||||
|
],
|
||||||
|
max_length=255,
|
||||||
|
null=True,
|
||||||
|
verbose_name="Type of cotisation",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -9,8 +9,8 @@ import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
def add_cheque(apps, schema_editor):
|
def add_cheque(apps, schema_editor):
|
||||||
ChequePayment = apps.get_model('cotisations', 'ChequePayment')
|
ChequePayment = apps.get_model("cotisations", "ChequePayment")
|
||||||
Payment = apps.get_model('cotisations', 'Paiement')
|
Payment = apps.get_model("cotisations", "Paiement")
|
||||||
for p in Payment.objects.filter(type_paiement=1):
|
for p in Payment.objects.filter(type_paiement=1):
|
||||||
cheque = ChequePayment()
|
cheque = ChequePayment()
|
||||||
cheque.payment = p
|
cheque.payment = p
|
||||||
|
@ -18,14 +18,12 @@ def add_cheque(apps, schema_editor):
|
||||||
|
|
||||||
|
|
||||||
def add_comnpay(apps, schema_editor):
|
def add_comnpay(apps, schema_editor):
|
||||||
ComnpayPayment = apps.get_model('cotisations', 'ComnpayPayment')
|
ComnpayPayment = apps.get_model("cotisations", "ComnpayPayment")
|
||||||
Payment = apps.get_model('cotisations', 'Paiement')
|
Payment = apps.get_model("cotisations", "Paiement")
|
||||||
AssoOption = apps.get_model('preferences', 'AssoOption')
|
AssoOption = apps.get_model("preferences", "AssoOption")
|
||||||
options, _created = AssoOption.objects.get_or_create()
|
options, _created = AssoOption.objects.get_or_create()
|
||||||
try:
|
try:
|
||||||
payment = Payment.objects.get(
|
payment = Payment.objects.get(moyen="Rechargement en ligne")
|
||||||
moyen='Rechargement en ligne'
|
|
||||||
)
|
|
||||||
except Payment.DoesNotExist:
|
except Payment.DoesNotExist:
|
||||||
return
|
return
|
||||||
comnpay = ComnpayPayment()
|
comnpay = ComnpayPayment()
|
||||||
|
@ -38,11 +36,11 @@ def add_comnpay(apps, schema_editor):
|
||||||
|
|
||||||
|
|
||||||
def add_solde(apps, schema_editor):
|
def add_solde(apps, schema_editor):
|
||||||
OptionalUser = apps.get_model('preferences', 'OptionalUser')
|
OptionalUser = apps.get_model("preferences", "OptionalUser")
|
||||||
options, _created = OptionalUser.objects.get_or_create()
|
options, _created = OptionalUser.objects.get_or_create()
|
||||||
|
|
||||||
Payment = apps.get_model('cotisations', 'Paiement')
|
Payment = apps.get_model("cotisations", "Paiement")
|
||||||
BalancePayment = apps.get_model('cotisations', 'BalancePayment')
|
BalancePayment = apps.get_model("cotisations", "BalancePayment")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
solde = Payment.objects.get(moyen="solde")
|
solde = Payment.objects.get(moyen="solde")
|
||||||
|
@ -60,73 +58,191 @@ def add_solde(apps, schema_editor):
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('preferences', '0044_remove_payment_pass'),
|
("preferences", "0044_remove_payment_pass"),
|
||||||
('cotisations', '0029_auto_20180414_2056'),
|
("cotisations", "0029_auto_20180414_2056"),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='paiement',
|
name="paiement",
|
||||||
options={'permissions': (('view_paiement', "Can see a payement's details"), ('use_every_payment', 'Can use every payement')), 'verbose_name': 'Payment method', 'verbose_name_plural': 'Payment methods'},
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("view_paiement", "Can see a payement's details"),
|
||||||
|
("use_every_payment", "Can use every payement"),
|
||||||
|
),
|
||||||
|
"verbose_name": "Payment method",
|
||||||
|
"verbose_name_plural": "Payment methods",
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='article',
|
name="article",
|
||||||
options={'permissions': (('view_article', "Can see an article's details"), ('buy_every_article', 'Can buy every_article')), 'verbose_name': 'Article', 'verbose_name_plural': 'Articles'},
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("view_article", "Can see an article's details"),
|
||||||
|
("buy_every_article", "Can buy every_article"),
|
||||||
|
),
|
||||||
|
"verbose_name": "Article",
|
||||||
|
"verbose_name_plural": "Articles",
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='paiement',
|
model_name="paiement",
|
||||||
name='available_for_everyone',
|
name="available_for_everyone",
|
||||||
field=models.BooleanField(default=False, verbose_name='Is available for every user'),
|
field=models.BooleanField(
|
||||||
|
default=False, verbose_name="Is available for every user"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='paiement',
|
model_name="paiement",
|
||||||
name='is_balance',
|
name="is_balance",
|
||||||
field=models.BooleanField(default=False, editable=False, help_text='There should be only one balance payment method.', verbose_name='Is user balance', validators=[cotisations.models.check_no_balance]),
|
field=models.BooleanField(
|
||||||
|
default=False,
|
||||||
|
editable=False,
|
||||||
|
help_text="There should be only one balance payment method.",
|
||||||
|
verbose_name="Is user balance",
|
||||||
|
validators=[cotisations.models.check_no_balance],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='available_for_everyone',
|
name="available_for_everyone",
|
||||||
field=models.BooleanField(default=False, verbose_name='Is available for every user'),
|
field=models.BooleanField(
|
||||||
|
default=False, verbose_name="Is available for every user"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='ChequePayment',
|
name="ChequePayment",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
(
|
||||||
('payment', models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='payment_method', to='cotisations.Paiement')),
|
"id",
|
||||||
|
models.AutoField(
|
||||||
|
auto_created=True,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
verbose_name="ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"payment",
|
||||||
|
models.OneToOneField(
|
||||||
|
editable=False,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="payment_method",
|
||||||
|
to="cotisations.Paiement",
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
bases=(cotisations.payment_methods.mixins.PaymentMethodMixin, models.Model),
|
bases=(cotisations.payment_methods.mixins.PaymentMethodMixin, models.Model),
|
||||||
options={'verbose_name': 'Cheque'},
|
options={"verbose_name": "Cheque"},
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='ComnpayPayment',
|
name="ComnpayPayment",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
(
|
||||||
('payment_credential', models.CharField(blank=True, default='', max_length=255, verbose_name='ComNpay VAD Number')),
|
"id",
|
||||||
('payment_pass', re2o.aes_field.AESEncryptedField(blank=True, max_length=255, null=True, verbose_name='ComNpay Secret Key')),
|
models.AutoField(
|
||||||
('payment', models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='payment_method', to='cotisations.Paiement')),
|
auto_created=True,
|
||||||
('minimum_payment', models.DecimalField(decimal_places=2, default=1, help_text='The minimal amount of money you have to use when paying with ComNpay', max_digits=5, verbose_name='Minimum payment')),
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
verbose_name="ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"payment_credential",
|
||||||
|
models.CharField(
|
||||||
|
blank=True,
|
||||||
|
default="",
|
||||||
|
max_length=255,
|
||||||
|
verbose_name="ComNpay VAD Number",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"payment_pass",
|
||||||
|
re2o.aes_field.AESEncryptedField(
|
||||||
|
blank=True,
|
||||||
|
max_length=255,
|
||||||
|
null=True,
|
||||||
|
verbose_name="ComNpay Secret Key",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"payment",
|
||||||
|
models.OneToOneField(
|
||||||
|
editable=False,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="payment_method",
|
||||||
|
to="cotisations.Paiement",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"minimum_payment",
|
||||||
|
models.DecimalField(
|
||||||
|
decimal_places=2,
|
||||||
|
default=1,
|
||||||
|
help_text="The minimal amount of money you have to use when paying with ComNpay",
|
||||||
|
max_digits=5,
|
||||||
|
verbose_name="Minimum payment",
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
bases=(cotisations.payment_methods.mixins.PaymentMethodMixin, models.Model),
|
bases=(cotisations.payment_methods.mixins.PaymentMethodMixin, models.Model),
|
||||||
options={'verbose_name': 'ComNpay'},
|
options={"verbose_name": "ComNpay"},
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='BalancePayment',
|
name="BalancePayment",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
(
|
||||||
('minimum_balance', models.DecimalField(decimal_places=2, default=0, help_text='The minimal amount of money allowed for the balance at the end of a payment. You can specify negative amount.', max_digits=5, verbose_name='Minimum balance')),
|
"id",
|
||||||
('payment', models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='payment_method', to='cotisations.Paiement')),
|
models.AutoField(
|
||||||
('maximum_balance', models.DecimalField(decimal_places=2, default=50, help_text='The maximal amount of money allowed for the balance.', max_digits=5, verbose_name='Maximum balance', null=True, blank=True)),
|
auto_created=True,
|
||||||
('credit_balance_allowed', models.BooleanField(default=False, verbose_name='Allow user to credit their balance')),
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
verbose_name="ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"minimum_balance",
|
||||||
|
models.DecimalField(
|
||||||
|
decimal_places=2,
|
||||||
|
default=0,
|
||||||
|
help_text="The minimal amount of money allowed for the balance at the end of a payment. You can specify negative amount.",
|
||||||
|
max_digits=5,
|
||||||
|
verbose_name="Minimum balance",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"payment",
|
||||||
|
models.OneToOneField(
|
||||||
|
editable=False,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="payment_method",
|
||||||
|
to="cotisations.Paiement",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"maximum_balance",
|
||||||
|
models.DecimalField(
|
||||||
|
decimal_places=2,
|
||||||
|
default=50,
|
||||||
|
help_text="The maximal amount of money allowed for the balance.",
|
||||||
|
max_digits=5,
|
||||||
|
verbose_name="Maximum balance",
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"credit_balance_allowed",
|
||||||
|
models.BooleanField(
|
||||||
|
default=False, verbose_name="Allow user to credit their balance"
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
bases=(cotisations.payment_methods.mixins.PaymentMethodMixin, models.Model),
|
bases=(cotisations.payment_methods.mixins.PaymentMethodMixin, models.Model),
|
||||||
options={'verbose_name': 'User Balance'},
|
options={"verbose_name": "User Balance"},
|
||||||
),
|
),
|
||||||
migrations.RunPython(add_comnpay),
|
migrations.RunPython(add_comnpay),
|
||||||
migrations.RunPython(add_cheque),
|
migrations.RunPython(add_cheque),
|
||||||
migrations.RunPython(add_solde),
|
migrations.RunPython(add_solde),
|
||||||
migrations.RemoveField(
|
migrations.RemoveField(model_name="paiement", name="type_paiement"),
|
||||||
model_name='paiement',
|
|
||||||
name='type_paiement',
|
|
||||||
),
|
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,14 +7,15 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0030_custom_payment")]
|
||||||
('cotisations', '0030_custom_payment'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='comnpaypayment',
|
model_name="comnpaypayment",
|
||||||
name='production',
|
name="production",
|
||||||
field=models.BooleanField(default=True, verbose_name='Production mode enabled (production url, instead of homologation)'),
|
field=models.BooleanField(
|
||||||
|
default=True,
|
||||||
|
verbose_name="Production mode enabled (production url, instead of homologation)",
|
||||||
),
|
),
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -10,8 +10,8 @@ import re2o.mixins
|
||||||
|
|
||||||
|
|
||||||
def reattribute_ids(apps, schema_editor):
|
def reattribute_ids(apps, schema_editor):
|
||||||
Facture = apps.get_model('cotisations', 'Facture')
|
Facture = apps.get_model("cotisations", "Facture")
|
||||||
BaseInvoice = apps.get_model('cotisations', 'BaseInvoice')
|
BaseInvoice = apps.get_model("cotisations", "BaseInvoice")
|
||||||
|
|
||||||
for f in Facture.objects.all():
|
for f in Facture.objects.all():
|
||||||
base = BaseInvoice.objects.create(id=f.pk)
|
base = BaseInvoice.objects.create(id=f.pk)
|
||||||
|
@ -22,21 +22,23 @@ def reattribute_ids(apps, schema_editor):
|
||||||
|
|
||||||
|
|
||||||
def update_rights(apps, schema_editor):
|
def update_rights(apps, schema_editor):
|
||||||
Permission = apps.get_model('auth', 'Permission')
|
Permission = apps.get_model("auth", "Permission")
|
||||||
|
|
||||||
# creates needed permissions
|
# creates needed permissions
|
||||||
app = apps.get_app_config('cotisations')
|
app = apps.get_app_config("cotisations")
|
||||||
app.models_module = True
|
app.models_module = True
|
||||||
create_permissions(app)
|
create_permissions(app)
|
||||||
app.models_module = False
|
app.models_module = False
|
||||||
|
|
||||||
ContentType = apps.get_model("contenttypes", "ContentType")
|
ContentType = apps.get_model("contenttypes", "ContentType")
|
||||||
content_type = ContentType.objects.get_for_model(Permission)
|
content_type = ContentType.objects.get_for_model(Permission)
|
||||||
former, created = Permission.objects.get_or_create(codename='change_facture_pdf', content_type=content_type)
|
former, created = Permission.objects.get_or_create(
|
||||||
new_1 = Permission.objects.get(codename='add_custominvoice')
|
codename="change_facture_pdf", content_type=content_type
|
||||||
new_2 = Permission.objects.get(codename='change_custominvoice')
|
)
|
||||||
new_3 = Permission.objects.get(codename='view_custominvoice')
|
new_1 = Permission.objects.get(codename="add_custominvoice")
|
||||||
new_4 = Permission.objects.get(codename='delete_custominvoice')
|
new_2 = Permission.objects.get(codename="change_custominvoice")
|
||||||
|
new_3 = Permission.objects.get(codename="view_custominvoice")
|
||||||
|
new_4 = Permission.objects.get(codename="delete_custominvoice")
|
||||||
for group in former.group_set.all():
|
for group in former.group_set.all():
|
||||||
group.permissions.remove(former)
|
group.permissions.remove(former)
|
||||||
group.permissions.add(new_1)
|
group.permissions.add(new_1)
|
||||||
|
@ -48,59 +50,105 @@ def update_rights(apps, schema_editor):
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0031_comnpaypayment_production")]
|
||||||
('cotisations', '0031_comnpaypayment_production'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='BaseInvoice',
|
name="BaseInvoice",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
(
|
||||||
('date', models.DateTimeField(auto_now_add=True, verbose_name='Date')),
|
"id",
|
||||||
|
models.AutoField(
|
||||||
|
auto_created=True,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
verbose_name="ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("date", models.DateTimeField(auto_now_add=True, verbose_name="Date")),
|
||||||
],
|
],
|
||||||
bases=(re2o.mixins.RevMixin, re2o.mixins.AclMixin, re2o.field_permissions.FieldPermissionModelMixin, models.Model),
|
bases=(
|
||||||
|
re2o.mixins.RevMixin,
|
||||||
|
re2o.mixins.AclMixin,
|
||||||
|
re2o.field_permissions.FieldPermissionModelMixin,
|
||||||
|
models.Model,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='CustomInvoice',
|
name="CustomInvoice",
|
||||||
fields=[
|
fields=[
|
||||||
('baseinvoice_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='cotisations.BaseInvoice')),
|
(
|
||||||
('recipient', models.CharField(max_length=255, verbose_name='Recipient')),
|
"baseinvoice_ptr",
|
||||||
('payment', models.CharField(max_length=255, verbose_name='Payment type')),
|
models.OneToOneField(
|
||||||
('address', models.CharField(max_length=255, verbose_name='Address')),
|
auto_created=True,
|
||||||
('paid', models.BooleanField(verbose_name='Paid')),
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
parent_link=True,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
to="cotisations.BaseInvoice",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"recipient",
|
||||||
|
models.CharField(max_length=255, verbose_name="Recipient"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"payment",
|
||||||
|
models.CharField(max_length=255, verbose_name="Payment type"),
|
||||||
|
),
|
||||||
|
("address", models.CharField(max_length=255, verbose_name="Address")),
|
||||||
|
("paid", models.BooleanField(verbose_name="Paid")),
|
||||||
],
|
],
|
||||||
bases=('cotisations.baseinvoice',),
|
bases=("cotisations.baseinvoice",),
|
||||||
options={'permissions': (('view_custominvoice', 'Can view a custom invoice'),)},
|
options={
|
||||||
|
"permissions": (("view_custominvoice", "Can view a custom invoice"),)
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='baseinvoice_ptr',
|
name="baseinvoice_ptr",
|
||||||
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='cotisations.BaseInvoice', null=True),
|
field=models.OneToOneField(
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
to="cotisations.BaseInvoice",
|
||||||
|
null=True,
|
||||||
|
),
|
||||||
preserve_default=False,
|
preserve_default=False,
|
||||||
),
|
),
|
||||||
migrations.RunPython(reattribute_ids),
|
migrations.RunPython(reattribute_ids),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='facture',
|
name="facture",
|
||||||
field=models.ForeignKey(on_delete=models.CASCADE, verbose_name='Invoice', to='cotisations.BaseInvoice')
|
field=models.ForeignKey(
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
verbose_name="Invoice",
|
||||||
|
to="cotisations.BaseInvoice",
|
||||||
),
|
),
|
||||||
migrations.RemoveField(
|
|
||||||
model_name='facture',
|
|
||||||
name='id',
|
|
||||||
),
|
|
||||||
migrations.RemoveField(
|
|
||||||
model_name='facture',
|
|
||||||
name='date',
|
|
||||||
),
|
),
|
||||||
|
migrations.RemoveField(model_name="facture", name="id"),
|
||||||
|
migrations.RemoveField(model_name="facture", name="date"),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='baseinvoice_ptr',
|
name="baseinvoice_ptr",
|
||||||
field=models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='cotisations.BaseInvoice'),
|
field=models.OneToOneField(
|
||||||
|
auto_created=True,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
parent_link=True,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
to="cotisations.BaseInvoice",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.RunPython(update_rights),
|
migrations.RunPython(update_rights),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='facture',
|
name="facture",
|
||||||
options={'permissions': (('change_facture_control', 'Can change the "controlled" state'), ('view_facture', "Can see an invoice's details"), ('change_all_facture', 'Can edit all the previous invoices')), 'verbose_name': 'Invoice', 'verbose_name_plural': 'Invoices'},
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("change_facture_control", 'Can change the "controlled" state'),
|
||||||
|
("view_facture", "Can see an invoice's details"),
|
||||||
|
("change_all_facture", "Can edit all the previous invoices"),
|
||||||
|
),
|
||||||
|
"verbose_name": "Invoice",
|
||||||
|
"verbose_name_plural": "Invoices",
|
||||||
|
},
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -11,171 +11,294 @@ import re2o.aes_field
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0032_custom_invoice")]
|
||||||
('cotisations', '0032_custom_invoice'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='article',
|
name="article",
|
||||||
options={'permissions': (('view_article', 'Can view an article object'), ('buy_every_article', 'Can buy every article')), 'verbose_name': 'article', 'verbose_name_plural': 'articles'},
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("view_article", "Can view an article object"),
|
||||||
|
("buy_every_article", "Can buy every article"),
|
||||||
|
),
|
||||||
|
"verbose_name": "article",
|
||||||
|
"verbose_name_plural": "articles",
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='balancepayment',
|
name="balancepayment", options={"verbose_name": "user balance"}
|
||||||
options={'verbose_name': 'user balance'},
|
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='banque',
|
name="banque",
|
||||||
options={'permissions': (('view_banque', 'Can view a bank object'),), 'verbose_name': 'bank', 'verbose_name_plural': 'banks'},
|
options={
|
||||||
|
"permissions": (("view_banque", "Can view a bank object"),),
|
||||||
|
"verbose_name": "bank",
|
||||||
|
"verbose_name_plural": "banks",
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='cotisation',
|
name="cotisation",
|
||||||
options={'permissions': (('view_cotisation', 'Can view a subscription object'), ('change_all_cotisation', 'Can edit the previous subscriptions')), 'verbose_name': 'subscription', 'verbose_name_plural': 'subscriptions'},
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("view_cotisation", "Can view a subscription object"),
|
||||||
|
("change_all_cotisation", "Can edit the previous subscriptions"),
|
||||||
|
),
|
||||||
|
"verbose_name": "subscription",
|
||||||
|
"verbose_name_plural": "subscriptions",
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='custominvoice',
|
name="custominvoice",
|
||||||
options={'permissions': (('view_custominvoice', 'Can view a custom invoice object'),)},
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("view_custominvoice", "Can view a custom invoice object"),
|
||||||
|
)
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='facture',
|
name="facture",
|
||||||
options={'permissions': (('change_facture_control', 'Can edit the "controlled" state'), ('view_facture', 'Can view an invoice object'), ('change_all_facture', 'Can edit all the previous invoices')), 'verbose_name': 'invoice', 'verbose_name_plural': 'invoices'},
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("change_facture_control", 'Can edit the "controlled" state'),
|
||||||
|
("view_facture", "Can view an invoice object"),
|
||||||
|
("change_all_facture", "Can edit all the previous invoices"),
|
||||||
|
),
|
||||||
|
"verbose_name": "invoice",
|
||||||
|
"verbose_name_plural": "invoices",
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='paiement',
|
name="paiement",
|
||||||
options={'permissions': (('view_paiement', 'Can view a payment method object'), ('use_every_payment', 'Can use every payment method')), 'verbose_name': 'payment method', 'verbose_name_plural': 'payment methods'},
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("view_paiement", "Can view a payment method object"),
|
||||||
|
("use_every_payment", "Can use every payment method"),
|
||||||
|
),
|
||||||
|
"verbose_name": "payment method",
|
||||||
|
"verbose_name_plural": "payment methods",
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='vente',
|
name="vente",
|
||||||
options={'permissions': (('view_vente', 'Can view a purchase object'), ('change_all_vente', 'Can edit all the previous purchases')), 'verbose_name': 'purchase', 'verbose_name_plural': 'purchases'},
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("view_vente", "Can view a purchase object"),
|
||||||
|
("change_all_vente", "Can edit all the previous purchases"),
|
||||||
|
),
|
||||||
|
"verbose_name": "purchase",
|
||||||
|
"verbose_name_plural": "purchases",
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='available_for_everyone',
|
name="available_for_everyone",
|
||||||
field=models.BooleanField(default=False, verbose_name='is available for every user'),
|
field=models.BooleanField(
|
||||||
|
default=False, verbose_name="is available for every user"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='duration',
|
name="duration",
|
||||||
field=models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(0)], verbose_name='duration (in months)'),
|
field=models.PositiveIntegerField(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
validators=[django.core.validators.MinValueValidator(0)],
|
||||||
|
verbose_name="duration (in months)",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='name',
|
name="name",
|
||||||
field=models.CharField(max_length=255, verbose_name='designation'),
|
field=models.CharField(max_length=255, verbose_name="designation"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='prix',
|
name="prix",
|
||||||
field=models.DecimalField(decimal_places=2, max_digits=5, verbose_name='unit price'),
|
field=models.DecimalField(
|
||||||
|
decimal_places=2, max_digits=5, verbose_name="unit price"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='type_cotisation',
|
name="type_cotisation",
|
||||||
field=models.CharField(blank=True, choices=[('Connexion', 'Connection'), ('Adhesion', 'Membership'), ('All', 'Both of them')], default=None, max_length=255, null=True, verbose_name='subscription type'),
|
field=models.CharField(
|
||||||
|
blank=True,
|
||||||
|
choices=[
|
||||||
|
("Connexion", "Connection"),
|
||||||
|
("Adhesion", "Membership"),
|
||||||
|
("All", "Both of them"),
|
||||||
|
],
|
||||||
|
default=None,
|
||||||
|
max_length=255,
|
||||||
|
null=True,
|
||||||
|
verbose_name="subscription type",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='type_user',
|
name="type_user",
|
||||||
field=models.CharField(choices=[('Adherent', 'Member'), ('Club', 'Club'), ('All', 'Both of them')], default='All', max_length=255, verbose_name='type of users concerned'),
|
field=models.CharField(
|
||||||
|
choices=[
|
||||||
|
("Adherent", "Member"),
|
||||||
|
("Club", "Club"),
|
||||||
|
("All", "Both of them"),
|
||||||
|
],
|
||||||
|
default="All",
|
||||||
|
max_length=255,
|
||||||
|
verbose_name="type of users concerned",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='banque',
|
model_name="banque", name="name", field=models.CharField(max_length=255)
|
||||||
name='name',
|
|
||||||
field=models.CharField(max_length=255),
|
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='comnpaypayment',
|
model_name="comnpaypayment",
|
||||||
name='payment_credential',
|
name="payment_credential",
|
||||||
field=models.CharField(blank=True, default='', max_length=255, verbose_name='ComNpay VAT Number'),
|
field=models.CharField(
|
||||||
|
blank=True,
|
||||||
|
default="",
|
||||||
|
max_length=255,
|
||||||
|
verbose_name="ComNpay VAT Number",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='comnpaypayment',
|
model_name="comnpaypayment",
|
||||||
name='payment_pass',
|
name="payment_pass",
|
||||||
field=re2o.aes_field.AESEncryptedField(blank=True, max_length=255, null=True, verbose_name='ComNpay secret key'),
|
field=re2o.aes_field.AESEncryptedField(
|
||||||
|
blank=True, max_length=255, null=True, verbose_name="ComNpay secret key"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='comnpaypayment',
|
model_name="comnpaypayment",
|
||||||
name='production',
|
name="production",
|
||||||
field=models.BooleanField(default=True, verbose_name='Production mode enabled (production URL, instead of homologation)'),
|
field=models.BooleanField(
|
||||||
|
default=True,
|
||||||
|
verbose_name="Production mode enabled (production URL, instead of homologation)",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='cotisation',
|
model_name="cotisation",
|
||||||
name='date_end',
|
name="date_end",
|
||||||
field=models.DateTimeField(verbose_name='end date'),
|
field=models.DateTimeField(verbose_name="end date"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='cotisation',
|
model_name="cotisation",
|
||||||
name='date_start',
|
name="date_start",
|
||||||
field=models.DateTimeField(verbose_name='start date'),
|
field=models.DateTimeField(verbose_name="start date"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='cotisation',
|
model_name="cotisation",
|
||||||
name='type_cotisation',
|
name="type_cotisation",
|
||||||
field=models.CharField(choices=[('Connexion', 'Connection'), ('Adhesion', 'Membership'), ('All', 'Both of them')], default='All', max_length=255, verbose_name='subscription type'),
|
field=models.CharField(
|
||||||
|
choices=[
|
||||||
|
("Connexion", "Connection"),
|
||||||
|
("Adhesion", "Membership"),
|
||||||
|
("All", "Both of them"),
|
||||||
|
],
|
||||||
|
default="All",
|
||||||
|
max_length=255,
|
||||||
|
verbose_name="subscription type",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='cotisation',
|
model_name="cotisation",
|
||||||
name='vente',
|
name="vente",
|
||||||
field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to='cotisations.Vente', verbose_name='purchase'),
|
field=models.OneToOneField(
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
to="cotisations.Vente",
|
||||||
|
verbose_name="purchase",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='cheque',
|
name="cheque",
|
||||||
field=models.CharField(blank=True, max_length=255, verbose_name='cheque number'),
|
field=models.CharField(
|
||||||
|
blank=True, max_length=255, verbose_name="cheque number"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='control',
|
name="control",
|
||||||
field=models.BooleanField(default=False, verbose_name='controlled'),
|
field=models.BooleanField(default=False, verbose_name="controlled"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='valid',
|
name="valid",
|
||||||
field=models.BooleanField(default=True, verbose_name='validated'),
|
field=models.BooleanField(default=True, verbose_name="validated"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='paiement',
|
model_name="paiement",
|
||||||
name='available_for_everyone',
|
name="available_for_everyone",
|
||||||
field=models.BooleanField(default=False, verbose_name='is available for every user'),
|
field=models.BooleanField(
|
||||||
|
default=False, verbose_name="is available for every user"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='paiement',
|
model_name="paiement",
|
||||||
name='is_balance',
|
name="is_balance",
|
||||||
field=models.BooleanField(default=False, editable=False, help_text='There should be only one balance payment method.', validators=[cotisations.validators.check_no_balance], verbose_name='is user balance'),
|
field=models.BooleanField(
|
||||||
|
default=False,
|
||||||
|
editable=False,
|
||||||
|
help_text="There should be only one balance payment method.",
|
||||||
|
validators=[cotisations.validators.check_no_balance],
|
||||||
|
verbose_name="is user balance",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='paiement',
|
model_name="paiement",
|
||||||
name='moyen',
|
name="moyen",
|
||||||
field=models.CharField(max_length=255, verbose_name='method'),
|
field=models.CharField(max_length=255, verbose_name="method"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='duration',
|
name="duration",
|
||||||
field=models.PositiveIntegerField(blank=True, null=True, verbose_name='duration (in months)'),
|
field=models.PositiveIntegerField(
|
||||||
|
blank=True, null=True, verbose_name="duration (in months)"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='facture',
|
name="facture",
|
||||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cotisations.BaseInvoice', verbose_name='invoice'),
|
field=models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
to="cotisations.BaseInvoice",
|
||||||
|
verbose_name="invoice",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='name',
|
name="name",
|
||||||
field=models.CharField(max_length=255, verbose_name='article'),
|
field=models.CharField(max_length=255, verbose_name="article"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='number',
|
name="number",
|
||||||
field=models.IntegerField(validators=[django.core.validators.MinValueValidator(1)], verbose_name='amount'),
|
field=models.IntegerField(
|
||||||
|
validators=[django.core.validators.MinValueValidator(1)],
|
||||||
|
verbose_name="amount",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='prix',
|
name="prix",
|
||||||
field=models.DecimalField(decimal_places=2, max_digits=5, verbose_name='price'),
|
field=models.DecimalField(
|
||||||
|
decimal_places=2, max_digits=5, verbose_name="price"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='type_cotisation',
|
name="type_cotisation",
|
||||||
field=models.CharField(blank=True, choices=[('Connexion', 'Connection'), ('Adhesion', 'Membership'), ('All', 'Both of them')], max_length=255, null=True, verbose_name='subscription type'),
|
field=models.CharField(
|
||||||
|
blank=True,
|
||||||
|
choices=[
|
||||||
|
("Connexion", "Connection"),
|
||||||
|
("Adhesion", "Membership"),
|
||||||
|
("All", "Both of them"),
|
||||||
|
],
|
||||||
|
max_length=255,
|
||||||
|
null=True,
|
||||||
|
verbose_name="subscription type",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,14 +7,12 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0033_auto_20180818_1319")]
|
||||||
('cotisations', '0033_auto_20180818_1319'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='valid',
|
name="valid",
|
||||||
field=models.BooleanField(default=False, verbose_name='validated'),
|
field=models.BooleanField(default=False, verbose_name="validated"),
|
||||||
),
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -9,23 +9,35 @@ import django.db.models.deletion
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0034_auto_20180831_1532")]
|
||||||
('cotisations', '0034_auto_20180831_1532'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='NotePayment',
|
name="NotePayment",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
(
|
||||||
('server', models.CharField(max_length=255, verbose_name='server')),
|
"id",
|
||||||
('port', models.PositiveIntegerField(blank=True, null=True)),
|
models.AutoField(
|
||||||
('id_note', models.PositiveIntegerField(blank=True, null=True)),
|
auto_created=True,
|
||||||
('payment', models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='payment_method', to='cotisations.Paiement')),
|
primary_key=True,
|
||||||
],
|
serialize=False,
|
||||||
options={
|
verbose_name="ID",
|
||||||
'verbose_name': 'NoteKfet',
|
|
||||||
},
|
|
||||||
bases=(cotisations.payment_methods.mixins.PaymentMethodMixin, models.Model),
|
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
("server", models.CharField(max_length=255, verbose_name="server")),
|
||||||
|
("port", models.PositiveIntegerField(blank=True, null=True)),
|
||||||
|
("id_note", models.PositiveIntegerField(blank=True, null=True)),
|
||||||
|
(
|
||||||
|
"payment",
|
||||||
|
models.OneToOneField(
|
||||||
|
editable=False,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="payment_method",
|
||||||
|
to="cotisations.Paiement",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
options={"verbose_name": "NoteKfet"},
|
||||||
|
bases=(cotisations.payment_methods.mixins.PaymentMethodMixin, models.Model),
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,14 +7,12 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0035_notepayment")]
|
||||||
('cotisations', '0035_notepayment'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='custominvoice',
|
model_name="custominvoice",
|
||||||
name='remark',
|
name="remark",
|
||||||
field=models.TextField(blank=True, null=True, verbose_name='Remark'),
|
field=models.TextField(blank=True, null=True, verbose_name="Remark"),
|
||||||
),
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -8,21 +8,40 @@ import django.db.models.deletion
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0036_custominvoice_remark")]
|
||||||
('cotisations', '0036_custominvoice_remark'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='CostEstimate',
|
name="CostEstimate",
|
||||||
fields=[
|
fields=[
|
||||||
('custominvoice_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='cotisations.CustomInvoice')),
|
(
|
||||||
('validity', models.DurationField(verbose_name='Period of validity')),
|
"custominvoice_ptr",
|
||||||
('final_invoice', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='origin_cost_estimate', to='cotisations.CustomInvoice')),
|
models.OneToOneField(
|
||||||
|
auto_created=True,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
parent_link=True,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
to="cotisations.CustomInvoice",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("validity", models.DurationField(verbose_name="Period of validity")),
|
||||||
|
(
|
||||||
|
"final_invoice",
|
||||||
|
models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="origin_cost_estimate",
|
||||||
|
to="cotisations.CustomInvoice",
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'permissions': (('view_costestimate', 'Can view a cost estimate object'),),
|
"permissions": (
|
||||||
|
("view_costestimate", "Can view a cost estimate object"),
|
||||||
|
)
|
||||||
},
|
},
|
||||||
bases=('cotisations.custominvoice',),
|
bases=("cotisations.custominvoice",),
|
||||||
),
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -8,24 +8,30 @@ import django.db.models.deletion
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0037_costestimate")]
|
||||||
('cotisations', '0037_costestimate'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='costestimate',
|
model_name="costestimate",
|
||||||
name='final_invoice',
|
name="final_invoice",
|
||||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='origin_cost_estimate', to='cotisations.CustomInvoice'),
|
field=models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.SET_NULL,
|
||||||
|
related_name="origin_cost_estimate",
|
||||||
|
to="cotisations.CustomInvoice",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='costestimate',
|
model_name="costestimate",
|
||||||
name='validity',
|
name="validity",
|
||||||
field=models.DurationField(help_text='DD HH:MM:SS', verbose_name='Period of validity'),
|
field=models.DurationField(
|
||||||
|
help_text="DD HH:MM:SS", verbose_name="Period of validity"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='custominvoice',
|
model_name="custominvoice",
|
||||||
name='paid',
|
name="paid",
|
||||||
field=models.BooleanField(default=False, verbose_name='Paid'),
|
field=models.BooleanField(default=False, verbose_name="Paid"),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -9,20 +9,32 @@ import django.db.models.deletion
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0038_auto_20181231_1657")]
|
||||||
('cotisations', '0038_auto_20181231_1657'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='FreePayment',
|
name="FreePayment",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
(
|
||||||
('payment', models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='payment_method', to='cotisations.Paiement')),
|
"id",
|
||||||
],
|
models.AutoField(
|
||||||
options={
|
auto_created=True,
|
||||||
'verbose_name': 'Free payment',
|
primary_key=True,
|
||||||
},
|
serialize=False,
|
||||||
bases=(cotisations.payment_methods.mixins.PaymentMethodMixin, models.Model),
|
verbose_name="ID",
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"payment",
|
||||||
|
models.OneToOneField(
|
||||||
|
editable=False,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="payment_method",
|
||||||
|
to="cotisations.Paiement",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
options={"verbose_name": "Free payment"},
|
||||||
|
bases=(cotisations.payment_methods.mixins.PaymentMethodMixin, models.Model),
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -8,19 +8,27 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0039_freepayment")]
|
||||||
('cotisations', '0039_freepayment'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='duration_days',
|
name="duration_days",
|
||||||
field=models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(0)], verbose_name='duration (in days, will be added to duration in months)'),
|
field=models.PositiveIntegerField(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
validators=[django.core.validators.MinValueValidator(0)],
|
||||||
|
verbose_name="duration (in days, will be added to duration in months)",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='duration_days',
|
name="duration_days",
|
||||||
field=models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(0)], verbose_name='duration (in days, will be added to duration in months)'),
|
field=models.PositiveIntegerField(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
validators=[django.core.validators.MinValueValidator(0)],
|
||||||
|
verbose_name="duration (in days, will be added to duration in months)",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -8,34 +8,57 @@ import django.db.models.deletion
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0040_auto_20191002_2335")]
|
||||||
('cotisations', '0040_auto_20191002_2335'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='balancepayment',
|
model_name="balancepayment",
|
||||||
name='payment',
|
name="payment",
|
||||||
field=models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='payment_method_balance', to='cotisations.Paiement'),
|
field=models.OneToOneField(
|
||||||
|
editable=False,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="payment_method_balance",
|
||||||
|
to="cotisations.Paiement",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='chequepayment',
|
model_name="chequepayment",
|
||||||
name='payment',
|
name="payment",
|
||||||
field=models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='payment_method_cheque', to='cotisations.Paiement'),
|
field=models.OneToOneField(
|
||||||
|
editable=False,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="payment_method_cheque",
|
||||||
|
to="cotisations.Paiement",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='comnpaypayment',
|
model_name="comnpaypayment",
|
||||||
name='payment',
|
name="payment",
|
||||||
field=models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='payment_method_comnpay', to='cotisations.Paiement'),
|
field=models.OneToOneField(
|
||||||
|
editable=False,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="payment_method_comnpay",
|
||||||
|
to="cotisations.Paiement",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='freepayment',
|
model_name="freepayment",
|
||||||
name='payment',
|
name="payment",
|
||||||
field=models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='payment_method_free', to='cotisations.Paiement'),
|
field=models.OneToOneField(
|
||||||
|
editable=False,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="payment_method_free",
|
||||||
|
to="cotisations.Paiement",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='notepayment',
|
model_name="notepayment",
|
||||||
name='payment',
|
name="payment",
|
||||||
field=models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='payment_method_note', to='cotisations.Paiement'),
|
field=models.OneToOneField(
|
||||||
|
editable=False,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="payment_method_note",
|
||||||
|
to="cotisations.Paiement",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -19,4 +19,3 @@
|
||||||
# You should have received a copy of the GNU General Public License along
|
# You should have received a copy of the GNU General Public License along
|
||||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -129,10 +129,4 @@ method to your model, where `form` is an instance of
|
||||||
|
|
||||||
from . import comnpay, cheque, balance, note_kfet, free, urls
|
from . import comnpay, cheque, balance, note_kfet, free, urls
|
||||||
|
|
||||||
PAYMENT_METHODS = [
|
PAYMENT_METHODS = [comnpay, cheque, balance, note_kfet, free]
|
||||||
comnpay,
|
|
||||||
cheque,
|
|
||||||
balance,
|
|
||||||
note_kfet,
|
|
||||||
free
|
|
||||||
]
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
This module contains a method to pay online using user balance.
|
This module contains a method to pay online using user balance.
|
||||||
"""
|
"""
|
||||||
from . import models
|
from . import models
|
||||||
|
|
||||||
NAME = "BALANCE"
|
NAME = "BALANCE"
|
||||||
|
|
||||||
PaymentMethod = models.BalancePayment
|
PaymentMethod = models.BalancePayment
|
||||||
|
|
|
@ -40,12 +40,13 @@ class BalancePayment(PaymentMethodMixin, models.Model):
|
||||||
payment = models.OneToOneField(
|
payment = models.OneToOneField(
|
||||||
Paiement,
|
Paiement,
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
related_name='payment_method_balance',
|
related_name="payment_method_balance",
|
||||||
editable=False
|
editable=False,
|
||||||
)
|
)
|
||||||
minimum_balance = models.DecimalField(
|
minimum_balance = models.DecimalField(
|
||||||
verbose_name=_("Minimum balance"),
|
verbose_name=_("Minimum balance"),
|
||||||
help_text=_("The minimal amount of money allowed for the balance"
|
help_text=_(
|
||||||
|
"The minimal amount of money allowed for the balance"
|
||||||
" at the end of a payment. You can specify negative "
|
" at the end of a payment. You can specify negative "
|
||||||
"amount."
|
"amount."
|
||||||
),
|
),
|
||||||
|
@ -63,8 +64,7 @@ class BalancePayment(PaymentMethodMixin, models.Model):
|
||||||
null=True,
|
null=True,
|
||||||
)
|
)
|
||||||
credit_balance_allowed = models.BooleanField(
|
credit_balance_allowed = models.BooleanField(
|
||||||
verbose_name=_("Allow user to credit their balance"),
|
verbose_name=_("Allow user to credit their balance"), default=False
|
||||||
default=False,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def end_payment(self, invoice, request):
|
def end_payment(self, invoice, request):
|
||||||
|
@ -74,27 +74,17 @@ class BalancePayment(PaymentMethodMixin, models.Model):
|
||||||
user = invoice.user
|
user = invoice.user
|
||||||
total_price = invoice.prix_total()
|
total_price = invoice.prix_total()
|
||||||
if user.solde - total_price < self.minimum_balance:
|
if user.solde - total_price < self.minimum_balance:
|
||||||
messages.error(
|
messages.error(request, _("Your balance is too low for this operation."))
|
||||||
request,
|
return redirect(reverse("users:profil", kwargs={"userid": user.id}))
|
||||||
_("Your balance is too low for this operation.")
|
return invoice.paiement.end_payment(invoice, request, use_payment_method=False)
|
||||||
)
|
|
||||||
return redirect(reverse(
|
|
||||||
'users:profil',
|
|
||||||
kwargs={'userid': user.id}
|
|
||||||
))
|
|
||||||
return invoice.paiement.end_payment(
|
|
||||||
invoice,
|
|
||||||
request,
|
|
||||||
use_payment_method=False
|
|
||||||
)
|
|
||||||
|
|
||||||
def valid_form(self, form):
|
def valid_form(self, form):
|
||||||
"""Checks that there is not already a balance payment method."""
|
"""Checks that there is not already a balance payment method."""
|
||||||
p = Paiement.objects.filter(is_balance=True)
|
p = Paiement.objects.filter(is_balance=True)
|
||||||
if len(p) > 0:
|
if len(p) > 0:
|
||||||
form.add_error(
|
form.add_error(
|
||||||
'payment_method',
|
"payment_method",
|
||||||
_("There is already a payment method for user balance.")
|
_("There is already a payment method for user balance."),
|
||||||
)
|
)
|
||||||
|
|
||||||
def alter_payment(self, payment):
|
def alter_payment(self, payment):
|
||||||
|
@ -107,12 +97,11 @@ class BalancePayment(PaymentMethodMixin, models.Model):
|
||||||
"""
|
"""
|
||||||
return (
|
return (
|
||||||
user.solde - price >= self.minimum_balance,
|
user.solde - price >= self.minimum_balance,
|
||||||
_("Your balance is too low for this operation.")
|
_("Your balance is too low for this operation."),
|
||||||
)
|
)
|
||||||
|
|
||||||
def can_credit_balance(self, user_request):
|
def can_credit_balance(self, user_request):
|
||||||
return (
|
return (
|
||||||
len(Paiement.find_allowed_payments(user_request)
|
len(Paiement.find_allowed_payments(user_request).exclude(is_balance=True))
|
||||||
.exclude(is_balance=True)) > 0
|
> 0
|
||||||
) and self.credit_balance_allowed
|
) and self.credit_balance_allowed
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
This module contains a method to pay online using cheque.
|
This module contains a method to pay online using cheque.
|
||||||
"""
|
"""
|
||||||
from . import models, urls, views
|
from . import models, urls, views
|
||||||
|
|
||||||
NAME = "CHEQUE"
|
NAME = "CHEQUE"
|
||||||
|
|
||||||
PaymentMethod = models.ChequePayment
|
PaymentMethod = models.ChequePayment
|
||||||
|
|
|
@ -26,6 +26,7 @@ from cotisations.models import Facture as Invoice
|
||||||
|
|
||||||
class InvoiceForm(FormRevMixin, forms.ModelForm):
|
class InvoiceForm(FormRevMixin, forms.ModelForm):
|
||||||
"""A simple form to get the bank a the cheque number."""
|
"""A simple form to get the bank a the cheque number."""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Invoice
|
model = Invoice
|
||||||
fields = ['banque', 'cheque']
|
fields = ["banque", "cheque"]
|
||||||
|
|
|
@ -38,16 +38,14 @@ class ChequePayment(PaymentMethodMixin, models.Model):
|
||||||
payment = models.OneToOneField(
|
payment = models.OneToOneField(
|
||||||
Paiement,
|
Paiement,
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
related_name='payment_method_cheque',
|
related_name="payment_method_cheque",
|
||||||
editable=False
|
editable=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
def end_payment(self, invoice, request):
|
def end_payment(self, invoice, request):
|
||||||
"""Invalidates the invoice then redirect the user towards a view asking
|
"""Invalidates the invoice then redirect the user towards a view asking
|
||||||
for informations to add to the invoice before validating it.
|
for informations to add to the invoice before validating it.
|
||||||
"""
|
"""
|
||||||
return redirect(reverse(
|
return redirect(
|
||||||
'cotisations:cheque:validate',
|
reverse("cotisations:cheque:validate", kwargs={"invoice_pk": invoice.pk})
|
||||||
kwargs={'invoice_pk': invoice.pk}
|
)
|
||||||
))
|
|
||||||
|
|
||||||
|
|
|
@ -21,10 +21,4 @@
|
||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [url(r"^validate/(?P<invoice_pk>[0-9]+)$", views.cheque, name="validate")]
|
||||||
url(
|
|
||||||
r'^validate/(?P<invoice_pk>[0-9]+)$',
|
|
||||||
views.cheque,
|
|
||||||
name='validate'
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
|
@ -42,29 +42,17 @@ def cheque(request, invoice_pk):
|
||||||
invoice = get_object_or_404(Invoice, pk=invoice_pk)
|
invoice = get_object_or_404(Invoice, pk=invoice_pk)
|
||||||
payment_method = find_payment_method(invoice.paiement)
|
payment_method = find_payment_method(invoice.paiement)
|
||||||
if invoice.valid or not isinstance(payment_method, ChequePayment):
|
if invoice.valid or not isinstance(payment_method, ChequePayment):
|
||||||
messages.error(
|
messages.error(request, _("You can't pay this invoice with a cheque."))
|
||||||
request,
|
return redirect(reverse("users:profil", kwargs={"userid": request.user.pk}))
|
||||||
_("You can't pay this invoice with a cheque.")
|
|
||||||
)
|
|
||||||
return redirect(reverse(
|
|
||||||
'users:profil',
|
|
||||||
kwargs={'userid': request.user.pk}
|
|
||||||
))
|
|
||||||
form = InvoiceForm(request.POST or None, instance=invoice)
|
form = InvoiceForm(request.POST or None, instance=invoice)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.instance.valid = True
|
form.instance.valid = True
|
||||||
form.save()
|
form.save()
|
||||||
return form.instance.paiement.end_payment(
|
return form.instance.paiement.end_payment(
|
||||||
form.instance,
|
form.instance, request, use_payment_method=False
|
||||||
request,
|
|
||||||
use_payment_method=False
|
|
||||||
)
|
)
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
'cotisations/payment.html',
|
"cotisations/payment.html",
|
||||||
{
|
{"form": form, "amount": invoice.prix_total()},
|
||||||
'form': form,
|
|
||||||
'amount': invoice.prix_total()
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -22,5 +22,6 @@
|
||||||
This module contains a method to pay online using comnpay.
|
This module contains a method to pay online using comnpay.
|
||||||
"""
|
"""
|
||||||
from . import models, urls, views
|
from . import models, urls, views
|
||||||
|
|
||||||
NAME = "COMNPAY"
|
NAME = "COMNPAY"
|
||||||
PaymentMethod = models.ComnpayPayment
|
PaymentMethod = models.ComnpayPayment
|
||||||
|
|
|
@ -10,13 +10,21 @@ import hashlib
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
|
|
||||||
class Transaction():
|
class Transaction:
|
||||||
""" The class representing a transaction with all the functions
|
""" The class representing a transaction with all the functions
|
||||||
used during the negociation
|
used during the negociation
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, vad_number="", secret_key="", urlRetourOK="",
|
def __init__(
|
||||||
urlRetourNOK="", urlIPN="", source="", typeTr="D"):
|
self,
|
||||||
|
vad_number="",
|
||||||
|
secret_key="",
|
||||||
|
urlRetourOK="",
|
||||||
|
urlRetourNOK="",
|
||||||
|
urlIPN="",
|
||||||
|
source="",
|
||||||
|
typeTr="D",
|
||||||
|
):
|
||||||
self.vad_number = vad_number
|
self.vad_number = vad_number
|
||||||
self.secret_key = secret_key
|
self.secret_key = secret_key
|
||||||
self.urlRetourOK = urlRetourOK
|
self.urlRetourOK = urlRetourOK
|
||||||
|
@ -26,8 +34,7 @@ class Transaction():
|
||||||
self.typeTr = typeTr
|
self.typeTr = typeTr
|
||||||
self.idTransaction = ""
|
self.idTransaction = ""
|
||||||
|
|
||||||
def buildSecretHTML(self, produit="Produit", montant="0.00",
|
def buildSecretHTML(self, produit="Produit", montant="0.00", idTransaction=""):
|
||||||
idTransaction=""):
|
|
||||||
""" Build an HTML hidden form with the different parameters for the
|
""" Build an HTML hidden form with the different parameters for the
|
||||||
transaction
|
transaction
|
||||||
"""
|
"""
|
||||||
|
@ -43,30 +50,26 @@ class Transaction():
|
||||||
idTPE=self.vad_number,
|
idTPE=self.vad_number,
|
||||||
idTransaction=self.idTransaction,
|
idTransaction=self.idTransaction,
|
||||||
devise="EUR",
|
devise="EUR",
|
||||||
lang='fr',
|
lang="fr",
|
||||||
nom_produit=produit,
|
nom_produit=produit,
|
||||||
source=self.source,
|
source=self.source,
|
||||||
urlRetourOK=self.urlRetourOK,
|
urlRetourOK=self.urlRetourOK,
|
||||||
urlRetourNOK=self.urlRetourNOK,
|
urlRetourNOK=self.urlRetourNOK,
|
||||||
typeTr=str(self.typeTr)
|
typeTr=str(self.typeTr),
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.urlIPN != "":
|
if self.urlIPN != "":
|
||||||
array_tpe['urlIPN'] = self.urlIPN
|
array_tpe["urlIPN"] = self.urlIPN
|
||||||
|
|
||||||
array_tpe['key'] = self.secret_key
|
array_tpe["key"] = self.secret_key
|
||||||
strWithKey = base64.b64encode(bytes(
|
strWithKey = base64.b64encode(bytes("|".join(array_tpe.values()), "utf-8"))
|
||||||
'|'.join(array_tpe.values()),
|
|
||||||
'utf-8'
|
|
||||||
))
|
|
||||||
del array_tpe["key"]
|
del array_tpe["key"]
|
||||||
array_tpe['sec'] = hashlib.sha512(strWithKey).hexdigest()
|
array_tpe["sec"] = hashlib.sha512(strWithKey).hexdigest()
|
||||||
|
|
||||||
ret = ""
|
ret = ""
|
||||||
for key in array_tpe:
|
for key in array_tpe:
|
||||||
ret += '<input type="hidden" name="{k}" value="{v}"/>'.format(
|
ret += '<input type="hidden" name="{k}" value="{v}"/>'.format(
|
||||||
k=key,
|
k=key, v=array_tpe[key]
|
||||||
v=array_tpe[key]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
@ -75,12 +78,13 @@ class Transaction():
|
||||||
def validSec(values, secret_key):
|
def validSec(values, secret_key):
|
||||||
""" Check if the secret value is correct """
|
""" Check if the secret value is correct """
|
||||||
if "sec" in values:
|
if "sec" in values:
|
||||||
sec = values['sec']
|
sec = values["sec"]
|
||||||
del values["sec"]
|
del values["sec"]
|
||||||
strWithKey = hashlib.sha512(base64.b64encode(bytes(
|
strWithKey = hashlib.sha512(
|
||||||
'|'.join(values.values()) + "|" + secret_key,
|
base64.b64encode(
|
||||||
'utf-8'
|
bytes("|".join(values.values()) + "|" + secret_key, "utf-8")
|
||||||
))).hexdigest()
|
)
|
||||||
|
).hexdigest()
|
||||||
return strWithKey.upper() == sec.upper()
|
return strWithKey.upper() == sec.upper()
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -41,39 +41,36 @@ class ComnpayPayment(PaymentMethodMixin, models.Model):
|
||||||
payment = models.OneToOneField(
|
payment = models.OneToOneField(
|
||||||
Paiement,
|
Paiement,
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
related_name='payment_method_comnpay',
|
related_name="payment_method_comnpay",
|
||||||
editable=False
|
editable=False,
|
||||||
)
|
)
|
||||||
payment_credential = models.CharField(
|
payment_credential = models.CharField(
|
||||||
max_length=255,
|
max_length=255, default="", blank=True, verbose_name=_("ComNpay VAT Number")
|
||||||
default='',
|
|
||||||
blank=True,
|
|
||||||
verbose_name=_("ComNpay VAT Number"),
|
|
||||||
)
|
)
|
||||||
payment_pass = AESEncryptedField(
|
payment_pass = AESEncryptedField(
|
||||||
max_length=255,
|
max_length=255, null=True, blank=True, verbose_name=_("ComNpay secret key")
|
||||||
null=True,
|
|
||||||
blank=True,
|
|
||||||
verbose_name=_("ComNpay secret key"),
|
|
||||||
)
|
)
|
||||||
minimum_payment = models.DecimalField(
|
minimum_payment = models.DecimalField(
|
||||||
verbose_name=_("Minimum payment"),
|
verbose_name=_("Minimum payment"),
|
||||||
help_text=_("The minimal amount of money you have to use when paying"
|
help_text=_(
|
||||||
" with ComNpay"),
|
"The minimal amount of money you have to use when paying" " with ComNpay"
|
||||||
|
),
|
||||||
max_digits=5,
|
max_digits=5,
|
||||||
decimal_places=2,
|
decimal_places=2,
|
||||||
default=1,
|
default=1,
|
||||||
)
|
)
|
||||||
production = models.BooleanField(
|
production = models.BooleanField(
|
||||||
default=True,
|
default=True,
|
||||||
verbose_name=_("Production mode enabled (production URL, instead of homologation)"),
|
verbose_name=_(
|
||||||
|
"Production mode enabled (production URL, instead of homologation)"
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
def return_url_comnpay(self):
|
def return_url_comnpay(self):
|
||||||
if self.production:
|
if self.production:
|
||||||
return 'https://secure.comnpay.com'
|
return "https://secure.comnpay.com"
|
||||||
else:
|
else:
|
||||||
return 'https://secure.homologation.comnpay.com'
|
return "https://secure.homologation.comnpay.com"
|
||||||
|
|
||||||
def end_payment(self, invoice, request):
|
def end_payment(self, invoice, request):
|
||||||
"""
|
"""
|
||||||
|
@ -85,32 +82,36 @@ class ComnpayPayment(PaymentMethodMixin, models.Model):
|
||||||
p = Transaction(
|
p = Transaction(
|
||||||
str(self.payment_credential),
|
str(self.payment_credential),
|
||||||
str(self.payment_pass),
|
str(self.payment_pass),
|
||||||
'https://' + host + reverse(
|
"https://"
|
||||||
'cotisations:comnpay:accept_payment',
|
+ host
|
||||||
kwargs={'factureid': invoice.id}
|
+ reverse(
|
||||||
|
"cotisations:comnpay:accept_payment", kwargs={"factureid": invoice.id}
|
||||||
),
|
),
|
||||||
'https://' + host + reverse('cotisations:comnpay:refuse_payment'),
|
"https://" + host + reverse("cotisations:comnpay:refuse_payment"),
|
||||||
'https://' + host + reverse('cotisations:comnpay:ipn'),
|
"https://" + host + reverse("cotisations:comnpay:ipn"),
|
||||||
"",
|
"",
|
||||||
"D"
|
"D",
|
||||||
)
|
)
|
||||||
|
|
||||||
r = {
|
r = {
|
||||||
'action': self.return_url_comnpay(),
|
"action": self.return_url_comnpay(),
|
||||||
'method': 'POST',
|
"method": "POST",
|
||||||
'content': p.buildSecretHTML(
|
"content": p.buildSecretHTML(
|
||||||
_("Pay invoice number ") + str(invoice.id),
|
_("Pay invoice number ") + str(invoice.id),
|
||||||
invoice.prix_total(),
|
invoice.prix_total(),
|
||||||
idTransaction=str(invoice.id)
|
idTransaction=str(invoice.id),
|
||||||
),
|
),
|
||||||
'amount': invoice.prix_total(),
|
"amount": invoice.prix_total(),
|
||||||
}
|
}
|
||||||
return render(request, 'cotisations/payment.html', r)
|
return render(request, "cotisations/payment.html", r)
|
||||||
|
|
||||||
def check_price(self, price, *args, **kwargs):
|
def check_price(self, price, *args, **kwargs):
|
||||||
"""Checks that the price meets the requirement to be paid with ComNpay.
|
"""Checks that the price meets the requirement to be paid with ComNpay.
|
||||||
"""
|
"""
|
||||||
return ((price >= self.minimum_payment),
|
return (
|
||||||
_("In order to pay your invoice with ComNpay, the price must"
|
(price >= self.minimum_payment),
|
||||||
" be greater than {} €.").format(self.minimum_payment))
|
_(
|
||||||
|
"In order to pay your invoice with ComNpay, the price must"
|
||||||
|
" be greater than {} €."
|
||||||
|
).format(self.minimum_payment),
|
||||||
|
)
|
||||||
|
|
|
@ -22,19 +22,7 @@ from django.conf.urls import url
|
||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(
|
url(r"^accept/(?P<factureid>[0-9]+)$", views.accept_payment, name="accept_payment"),
|
||||||
r'^accept/(?P<factureid>[0-9]+)$',
|
url(r"^refuse/$", views.refuse_payment, name="refuse_payment"),
|
||||||
views.accept_payment,
|
url(r"^ipn/$", views.ipn, name="ipn"),
|
||||||
name='accept_payment'
|
|
||||||
),
|
|
||||||
url(
|
|
||||||
r'^refuse/$',
|
|
||||||
views.refuse_payment,
|
|
||||||
name='refuse_payment'
|
|
||||||
),
|
|
||||||
url(
|
|
||||||
r'^ipn/$',
|
|
||||||
views.ipn,
|
|
||||||
name='ipn'
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -50,26 +50,24 @@ def accept_payment(request, factureid):
|
||||||
if invoice.valid:
|
if invoice.valid:
|
||||||
messages.success(
|
messages.success(
|
||||||
request,
|
request,
|
||||||
_("The payment of %(amount)s € was accepted.") % {
|
_("The payment of %(amount)s € was accepted.")
|
||||||
'amount': invoice.prix_total()
|
% {"amount": invoice.prix_total()},
|
||||||
}
|
|
||||||
)
|
)
|
||||||
# In case a cotisation was bought, inform the user, the
|
# In case a cotisation was bought, inform the user, the
|
||||||
# cotisation time has been extended too
|
# cotisation time has been extended too
|
||||||
if any(purchase.type_cotisation
|
if any(purchase.type_cotisation for purchase in invoice.vente_set.all()):
|
||||||
for purchase in invoice.vente_set.all()):
|
|
||||||
messages.success(
|
messages.success(
|
||||||
request,
|
request,
|
||||||
_("The subscription of %(member_name)s was extended to"
|
_(
|
||||||
" %(end_date)s.") % {
|
"The subscription of %(member_name)s was extended to"
|
||||||
'member_name': invoice.user.pseudo,
|
" %(end_date)s."
|
||||||
'end_date': invoice.user.end_adhesion()
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
return redirect(reverse(
|
% {
|
||||||
'users:profil',
|
"member_name": invoice.user.pseudo,
|
||||||
kwargs={'userid': invoice.user.id}
|
"end_date": invoice.user.end_adhesion(),
|
||||||
))
|
},
|
||||||
|
)
|
||||||
|
return redirect(reverse("users:profil", kwargs={"userid": invoice.user.id}))
|
||||||
|
|
||||||
|
|
||||||
@csrf_exempt
|
@csrf_exempt
|
||||||
|
@ -79,14 +77,8 @@ def refuse_payment(request):
|
||||||
The view where the user is redirected when a comnpay payment has been
|
The view where the user is redirected when a comnpay payment has been
|
||||||
refused.
|
refused.
|
||||||
"""
|
"""
|
||||||
messages.error(
|
messages.error(request, _("The payment was refused."))
|
||||||
request,
|
return redirect(reverse("users:profil", kwargs={"userid": request.user.id}))
|
||||||
_("The payment was refused.")
|
|
||||||
)
|
|
||||||
return redirect(reverse(
|
|
||||||
'users:profil',
|
|
||||||
kwargs={'userid': request.user.id}
|
|
||||||
))
|
|
||||||
|
|
||||||
|
|
||||||
@csrf_exempt
|
@csrf_exempt
|
||||||
|
@ -97,27 +89,26 @@ def ipn(request):
|
||||||
Comnpay with 400 response if not or with a 200 response if yes.
|
Comnpay with 400 response if not or with a 200 response if yes.
|
||||||
"""
|
"""
|
||||||
p = Transaction()
|
p = Transaction()
|
||||||
order = ('idTpe', 'idTransaction', 'montant', 'result', 'sec', )
|
order = ("idTpe", "idTransaction", "montant", "result", "sec")
|
||||||
try:
|
try:
|
||||||
data = OrderedDict([(f, request.POST[f]) for f in order])
|
data = OrderedDict([(f, request.POST[f]) for f in order])
|
||||||
except MultiValueDictKeyError:
|
except MultiValueDictKeyError:
|
||||||
return HttpResponseBadRequest("HTTP/1.1 400 Bad Request")
|
return HttpResponseBadRequest("HTTP/1.1 400 Bad Request")
|
||||||
|
|
||||||
idTransaction = request.POST['idTransaction']
|
idTransaction = request.POST["idTransaction"]
|
||||||
try:
|
try:
|
||||||
factureid = int(idTransaction)
|
factureid = int(idTransaction)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return HttpResponseBadRequest("HTTP/1.1 400 Bad Request")
|
return HttpResponseBadRequest("HTTP/1.1 400 Bad Request")
|
||||||
|
|
||||||
facture = get_object_or_404(Facture, id=factureid)
|
facture = get_object_or_404(Facture, id=factureid)
|
||||||
payment_method = get_object_or_404(
|
payment_method = get_object_or_404(ComnpayPayment, payment=facture.paiement)
|
||||||
ComnpayPayment, payment=facture.paiement)
|
|
||||||
|
|
||||||
if not p.validSec(data, payment_method.payment_pass):
|
if not p.validSec(data, payment_method.payment_pass):
|
||||||
return HttpResponseBadRequest("HTTP/1.1 400 Bad Request")
|
return HttpResponseBadRequest("HTTP/1.1 400 Bad Request")
|
||||||
|
|
||||||
result = True if (request.POST['result'] == 'OK') else False
|
result = True if (request.POST["result"] == "OK") else False
|
||||||
idTpe = request.POST['idTpe']
|
idTpe = request.POST["idTpe"]
|
||||||
|
|
||||||
# Checking that the payment is actually for us.
|
# Checking that the payment is actually for us.
|
||||||
if not idTpe == payment_method.payment_credential:
|
if not idTpe == payment_method.payment_credential:
|
||||||
|
@ -136,4 +127,3 @@ def ipn(request):
|
||||||
# Everything worked we send a reponse to Comnpay indicating that
|
# Everything worked we send a reponse to Comnpay indicating that
|
||||||
# it's ok for them to proceed
|
# it's ok for them to proceed
|
||||||
return HttpResponse("HTTP/1.0 200 OK")
|
return HttpResponse("HTTP/1.0 200 OK")
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
from . import PAYMENT_METHODS
|
from . import PAYMENT_METHODS
|
||||||
from cotisations.utils import find_payment_method
|
from cotisations.utils import find_payment_method
|
||||||
|
|
||||||
|
|
||||||
def payment_method_factory(payment, *args, creation=True, **kwargs):
|
def payment_method_factory(payment, *args, creation=True, **kwargs):
|
||||||
"""This function finds the right payment method form for a given payment.
|
"""This function finds the right payment method form for a given payment.
|
||||||
|
|
||||||
|
@ -40,12 +41,10 @@ def payment_method_factory(payment, *args, creation=True, **kwargs):
|
||||||
Returns:
|
Returns:
|
||||||
A form or None
|
A form or None
|
||||||
"""
|
"""
|
||||||
payment_method = kwargs.pop('instance', find_payment_method(payment))
|
payment_method = kwargs.pop("instance", find_payment_method(payment))
|
||||||
if payment_method is not None:
|
if payment_method is not None:
|
||||||
return forms.modelform_factory(type(payment_method), fields='__all__')(
|
return forms.modelform_factory(type(payment_method), fields="__all__")(
|
||||||
*args,
|
*args, instance=payment_method, **kwargs
|
||||||
instance=payment_method,
|
|
||||||
**kwargs
|
|
||||||
)
|
)
|
||||||
elif creation:
|
elif creation:
|
||||||
return PaymentMethodForm(*args, **kwargs)
|
return PaymentMethodForm(*args, **kwargs)
|
||||||
|
@ -58,23 +57,24 @@ class PaymentMethodForm(forms.Form):
|
||||||
|
|
||||||
payment_method = forms.ChoiceField(
|
payment_method = forms.ChoiceField(
|
||||||
label=_("Special payment method"),
|
label=_("Special payment method"),
|
||||||
help_text=_("Warning: you will not be able to change the payment "
|
help_text=_(
|
||||||
|
"Warning: you will not be able to change the payment "
|
||||||
"method later. But you will be allowed to edit the other "
|
"method later. But you will be allowed to edit the other "
|
||||||
"options."
|
"options."
|
||||||
),
|
),
|
||||||
required=False
|
required=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(PaymentMethodForm, self).__init__(*args, **kwargs)
|
super(PaymentMethodForm, self).__init__(*args, **kwargs)
|
||||||
prefix = kwargs.get('prefix', None)
|
prefix = kwargs.get("prefix", None)
|
||||||
self.fields['payment_method'].choices = [(i,p.NAME) for (i,p) in enumerate(PAYMENT_METHODS)]
|
self.fields["payment_method"].choices = [
|
||||||
self.fields['payment_method'].choices.insert(0, ('', _('no')))
|
(i, p.NAME) for (i, p) in enumerate(PAYMENT_METHODS)
|
||||||
self.fields['payment_method'].widget.attrs = {
|
]
|
||||||
'id': 'paymentMethodSelect'
|
self.fields["payment_method"].choices.insert(0, ("", _("no")))
|
||||||
}
|
self.fields["payment_method"].widget.attrs = {"id": "paymentMethodSelect"}
|
||||||
self.templates = [
|
self.templates = [
|
||||||
forms.modelform_factory(p.PaymentMethod, fields='__all__')(prefix=prefix)
|
forms.modelform_factory(p.PaymentMethod, fields="__all__")(prefix=prefix)
|
||||||
for p in PAYMENT_METHODS
|
for p in PAYMENT_METHODS
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -84,29 +84,29 @@ class PaymentMethodForm(forms.Form):
|
||||||
found. Tries to call `payment_method.valid_form` if it exists.
|
found. Tries to call `payment_method.valid_form` if it exists.
|
||||||
"""
|
"""
|
||||||
super(PaymentMethodForm, self).clean()
|
super(PaymentMethodForm, self).clean()
|
||||||
choice = self.cleaned_data['payment_method']
|
choice = self.cleaned_data["payment_method"]
|
||||||
if choice=='':
|
if choice == "":
|
||||||
return
|
return
|
||||||
choice = int(choice)
|
choice = int(choice)
|
||||||
model = PAYMENT_METHODS[choice].PaymentMethod
|
model = PAYMENT_METHODS[choice].PaymentMethod
|
||||||
form = forms.modelform_factory(model, fields='__all__')(self.data, prefix=self.prefix)
|
form = forms.modelform_factory(model, fields="__all__")(
|
||||||
|
self.data, prefix=self.prefix
|
||||||
|
)
|
||||||
self.payment_method = form.save(commit=False)
|
self.payment_method = form.save(commit=False)
|
||||||
if hasattr(self.payment_method, 'valid_form'):
|
if hasattr(self.payment_method, "valid_form"):
|
||||||
self.payment_method.valid_form(self)
|
self.payment_method.valid_form(self)
|
||||||
return self.cleaned_data
|
return self.cleaned_data
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def save(self, payment, *args, **kwargs):
|
def save(self, payment, *args, **kwargs):
|
||||||
"""Saves the payment method.
|
"""Saves the payment method.
|
||||||
|
|
||||||
Tries to call `payment_method.alter_payment` if it exists.
|
Tries to call `payment_method.alter_payment` if it exists.
|
||||||
"""
|
"""
|
||||||
commit = kwargs.pop('commit', True)
|
commit = kwargs.pop("commit", True)
|
||||||
if not hasattr(self, 'payment_method'):
|
if not hasattr(self, "payment_method"):
|
||||||
return None
|
return None
|
||||||
self.payment_method.payment = payment
|
self.payment_method.payment = payment
|
||||||
if hasattr(self.payment_method, 'alter_payment'):
|
if hasattr(self.payment_method, "alter_payment"):
|
||||||
self.payment_method.alter_payment(payment)
|
self.payment_method.alter_payment(payment)
|
||||||
if commit:
|
if commit:
|
||||||
payment.save()
|
payment.save()
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
This module contains a method to pay online using user balance.
|
This module contains a method to pay online using user balance.
|
||||||
"""
|
"""
|
||||||
from . import models
|
from . import models
|
||||||
|
|
||||||
NAME = "FREE"
|
NAME = "FREE"
|
||||||
|
|
||||||
PaymentMethod = models.FreePayment
|
PaymentMethod = models.FreePayment
|
||||||
|
|
|
@ -38,24 +38,17 @@ class FreePayment(PaymentMethodMixin, models.Model):
|
||||||
payment = models.OneToOneField(
|
payment = models.OneToOneField(
|
||||||
Paiement,
|
Paiement,
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
related_name='payment_method_free',
|
related_name="payment_method_free",
|
||||||
editable=False
|
editable=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
def end_payment(self, invoice, request):
|
def end_payment(self, invoice, request):
|
||||||
"""Ends the payment normally.
|
"""Ends the payment normally.
|
||||||
"""
|
"""
|
||||||
return invoice.paiement.end_payment(
|
return invoice.paiement.end_payment(invoice, request, use_payment_method=False)
|
||||||
invoice,
|
|
||||||
request,
|
|
||||||
use_payment_method=False
|
|
||||||
)
|
|
||||||
|
|
||||||
def check_price(self, price, user, *args, **kwargs):
|
def check_price(self, price, user, *args, **kwargs):
|
||||||
"""Checks that the price meets the requirement to be paid with user
|
"""Checks that the price meets the requirement to be paid with user
|
||||||
balance.
|
balance.
|
||||||
"""
|
"""
|
||||||
return (
|
return (price == 0, _("You cannot validate this invoice for free."))
|
||||||
price == 0,
|
|
||||||
_("You cannot validate this invoice for free.")
|
|
||||||
)
|
|
||||||
|
|
|
@ -29,5 +29,4 @@ class PaymentMethodMixin:
|
||||||
|
|
||||||
Must return a HttpResponse-like object.
|
Must return a HttpResponse-like object.
|
||||||
"""
|
"""
|
||||||
return self.payment.end_payment(
|
return self.payment.end_payment(invoice, request, use_payment_method=False)
|
||||||
invoice, request, use_payment_method=False)
|
|
||||||
|
|
|
@ -22,5 +22,6 @@
|
||||||
This module contains a method to pay online using comnpay.
|
This module contains a method to pay online using comnpay.
|
||||||
"""
|
"""
|
||||||
from . import models, urls
|
from . import models, urls
|
||||||
|
|
||||||
NAME = "NOTE"
|
NAME = "NOTE"
|
||||||
PaymentMethod = models.NotePayment
|
PaymentMethod = models.NotePayment
|
||||||
|
|
|
@ -24,15 +24,11 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from cotisations.utils import find_payment_method
|
from cotisations.utils import find_payment_method
|
||||||
|
|
||||||
|
|
||||||
class NoteCredentialForm(forms.Form):
|
class NoteCredentialForm(forms.Form):
|
||||||
"""A special form to get credential to connect to a NoteKfet2015 server throught his API
|
"""A special form to get credential to connect to a NoteKfet2015 server throught his API
|
||||||
object.
|
object.
|
||||||
"""
|
"""
|
||||||
login = forms.CharField(
|
|
||||||
label=_("pseudo note")
|
|
||||||
)
|
|
||||||
password = forms.CharField(
|
|
||||||
label=_("Password"),
|
|
||||||
widget=forms.PasswordInput
|
|
||||||
)
|
|
||||||
|
|
||||||
|
login = forms.CharField(label=_("pseudo note"))
|
||||||
|
password = forms.CharField(label=_("Password"), widget=forms.PasswordInput)
|
||||||
|
|
|
@ -42,24 +42,16 @@ class NotePayment(PaymentMethodMixin, models.Model):
|
||||||
payment = models.OneToOneField(
|
payment = models.OneToOneField(
|
||||||
Paiement,
|
Paiement,
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
related_name = 'payment_method_note',
|
related_name="payment_method_note",
|
||||||
editable = False
|
editable=False,
|
||||||
)
|
|
||||||
server = models.CharField(
|
|
||||||
max_length=255,
|
|
||||||
verbose_name=_("server")
|
|
||||||
)
|
|
||||||
port = models.PositiveIntegerField(
|
|
||||||
blank = True,
|
|
||||||
null = True
|
|
||||||
)
|
|
||||||
id_note = models.PositiveIntegerField(
|
|
||||||
blank = True,
|
|
||||||
null = True
|
|
||||||
)
|
)
|
||||||
|
server = models.CharField(max_length=255, verbose_name=_("server"))
|
||||||
|
port = models.PositiveIntegerField(blank=True, null=True)
|
||||||
|
id_note = models.PositiveIntegerField(blank=True, null=True)
|
||||||
|
|
||||||
def end_payment(self, invoice, request):
|
def end_payment(self, invoice, request):
|
||||||
return redirect(reverse(
|
return redirect(
|
||||||
'cotisations:note_kfet:note_payment',
|
reverse(
|
||||||
kwargs={'factureid': invoice.id}
|
"cotisations:note_kfet:note_payment", kwargs={"factureid": invoice.id}
|
||||||
))
|
)
|
||||||
|
)
|
||||||
|
|
|
@ -12,13 +12,14 @@ import traceback
|
||||||
|
|
||||||
|
|
||||||
def get_response(socket):
|
def get_response(socket):
|
||||||
length_str = b''
|
length_str = b""
|
||||||
char = socket.recv(1)
|
char = socket.recv(1)
|
||||||
while char != b'\n':
|
while char != b"\n":
|
||||||
length_str += char
|
length_str += char
|
||||||
char = socket.recv(1)
|
char = socket.recv(1)
|
||||||
total = int(length_str)
|
total = int(length_str)
|
||||||
return json.loads(socket.recv(total).decode('utf-8'))
|
return json.loads(socket.recv(total).decode("utf-8"))
|
||||||
|
|
||||||
|
|
||||||
def connect(server, port):
|
def connect(server, port):
|
||||||
sock = socket.socket()
|
sock = socket.socket()
|
||||||
|
@ -35,6 +36,7 @@ def connect(server, port):
|
||||||
return (False, sock, "Serveur indisponible")
|
return (False, sock, "Serveur indisponible")
|
||||||
return (True, sock, "")
|
return (True, sock, "")
|
||||||
|
|
||||||
|
|
||||||
def login(server, port, username, password, masque=[[], [], True]):
|
def login(server, port, username, password, masque=[[], [], True]):
|
||||||
result, sock, err = connect(server, port)
|
result, sock, err = connect(server, port)
|
||||||
if not result:
|
if not result:
|
||||||
|
@ -43,7 +45,7 @@ def login(server, port, username, password, masque = [[], [], True]):
|
||||||
commande = ["login", [username, password, "bdd", masque]]
|
commande = ["login", [username, password, "bdd", masque]]
|
||||||
sock.send(json.dumps(commande).encode("utf-8"))
|
sock.send(json.dumps(commande).encode("utf-8"))
|
||||||
response = get_response(sock)
|
response = get_response(sock)
|
||||||
retcode = response['retcode']
|
retcode = response["retcode"]
|
||||||
if retcode == 0:
|
if retcode == 0:
|
||||||
return (True, sock, "")
|
return (True, sock, "")
|
||||||
elif retcode == 5:
|
elif retcode == 5:
|
||||||
|
@ -60,11 +62,28 @@ def don(sock, montant, id_note, facture):
|
||||||
Faire faire un don à l'id_note
|
Faire faire un don à l'id_note
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
sock.send(json.dumps(["dons", [[id_note], round(montant*100), "Facture : id=%s, designation=%s" % (facture.id, facture.name())]]).encode("utf-8"))
|
sock.send(
|
||||||
|
json.dumps(
|
||||||
|
[
|
||||||
|
"dons",
|
||||||
|
[
|
||||||
|
[id_note],
|
||||||
|
round(montant * 100),
|
||||||
|
"Facture : id=%s, designation=%s"
|
||||||
|
% (facture.id, facture.name()),
|
||||||
|
],
|
||||||
|
]
|
||||||
|
).encode("utf-8")
|
||||||
|
)
|
||||||
response = get_response(sock)
|
response = get_response(sock)
|
||||||
retcode = response['retcode']
|
retcode = response["retcode"]
|
||||||
transaction_retcode = response["msg"][0][0]
|
transaction_retcode = response["msg"][0][0]
|
||||||
if 0 < retcode < 100 or 200 <= retcode or 0 < transaction_retcode < 100 or 200 <= transaction_retcode:
|
if (
|
||||||
|
0 < retcode < 100
|
||||||
|
or 200 <= retcode
|
||||||
|
or 0 < transaction_retcode < 100
|
||||||
|
or 200 <= transaction_retcode
|
||||||
|
):
|
||||||
return (False, "Transaction échouée. (Solde trop négatif ?)")
|
return (False, "Transaction échouée. (Solde trop négatif ?)")
|
||||||
elif retcode == 0:
|
elif retcode == 0:
|
||||||
return (True, "")
|
return (True, "")
|
||||||
|
|
|
@ -23,8 +23,6 @@ from . import views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(
|
url(
|
||||||
r'^note_payment/(?P<factureid>[0-9]+)$',
|
r"^note_payment/(?P<factureid>[0-9]+)$", views.note_payment, name="note_payment"
|
||||||
views.note_payment,
|
)
|
||||||
name='note_payment'
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -39,13 +39,11 @@ from cotisations.models import Facture
|
||||||
from cotisations.utils import find_payment_method
|
from cotisations.utils import find_payment_method
|
||||||
from .models import NotePayment
|
from .models import NotePayment
|
||||||
from re2o.views import form
|
from re2o.views import form
|
||||||
from re2o.acl import (
|
from re2o.acl import can_create, can_edit
|
||||||
can_create,
|
|
||||||
can_edit
|
|
||||||
)
|
|
||||||
from .note import login, don
|
from .note import login, don
|
||||||
from .forms import NoteCredentialForm
|
from .forms import NoteCredentialForm
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@can_edit(Facture)
|
@can_edit(Facture)
|
||||||
def note_payment(request, facture, factureid):
|
def note_payment(request, facture, factureid):
|
||||||
|
@ -58,40 +56,38 @@ def note_payment(request, facture, factureid):
|
||||||
payment_method = find_payment_method(facture.paiement)
|
payment_method = find_payment_method(facture.paiement)
|
||||||
if not payment_method or not isinstance(payment_method, NotePayment):
|
if not payment_method or not isinstance(payment_method, NotePayment):
|
||||||
messages.error(request, _("Unknown error."))
|
messages.error(request, _("Unknown error."))
|
||||||
return redirect(reverse(
|
return redirect(reverse("users:profil", kwargs={"userid": user.id}))
|
||||||
'users:profil',
|
|
||||||
kwargs={'userid': user.id}
|
|
||||||
))
|
|
||||||
noteform = NoteCredentialForm(request.POST or None)
|
noteform = NoteCredentialForm(request.POST or None)
|
||||||
if noteform.is_valid():
|
if noteform.is_valid():
|
||||||
pseudo = noteform.cleaned_data['login']
|
pseudo = noteform.cleaned_data["login"]
|
||||||
password = noteform.cleaned_data['password']
|
password = noteform.cleaned_data["password"]
|
||||||
result, sock, err = login(payment_method.server, payment_method.port, pseudo, password)
|
result, sock, err = login(
|
||||||
|
payment_method.server, payment_method.port, pseudo, password
|
||||||
|
)
|
||||||
if not result:
|
if not result:
|
||||||
messages.error(request, err)
|
messages.error(request, err)
|
||||||
return form(
|
return form(
|
||||||
{'form': noteform, 'amount': facture.prix_total()},
|
{"form": noteform, "amount": facture.prix_total()},
|
||||||
"cotisations/payment.html",
|
"cotisations/payment.html",
|
||||||
request
|
request,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
result, err = don(sock, facture.prix_total(), payment_method.id_note, facture)
|
result, err = don(
|
||||||
|
sock, facture.prix_total(), payment_method.id_note, facture
|
||||||
|
)
|
||||||
if not result:
|
if not result:
|
||||||
messages.error(request, err)
|
messages.error(request, err)
|
||||||
return form(
|
return form(
|
||||||
{'form': noteform, 'amount': facture.prix_total()},
|
{"form": noteform, "amount": facture.prix_total()},
|
||||||
"cotisations/payment.html",
|
"cotisations/payment.html",
|
||||||
request
|
request,
|
||||||
)
|
)
|
||||||
facture.valid = True
|
facture.valid = True
|
||||||
facture.save()
|
facture.save()
|
||||||
messages.success(request, _("The payment with note was done."))
|
messages.success(request, _("The payment with note was done."))
|
||||||
return redirect(reverse(
|
return redirect(reverse("users:profil", kwargs={"userid": user.id}))
|
||||||
'users:profil',
|
|
||||||
kwargs={'userid': user.id}
|
|
||||||
))
|
|
||||||
return form(
|
return form(
|
||||||
{'form': noteform, 'amount': facture.prix_total()},
|
{"form": noteform, "amount": facture.prix_total()},
|
||||||
"cotisations/payment.html",
|
"cotisations/payment.html",
|
||||||
request
|
request,
|
||||||
)
|
)
|
||||||
|
|
|
@ -22,7 +22,7 @@ from django.conf.urls import include, url
|
||||||
from . import comnpay, cheque, note_kfet
|
from . import comnpay, cheque, note_kfet
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^comnpay/', include(comnpay.urls, namespace='comnpay')),
|
url(r"^comnpay/", include(comnpay.urls, namespace="comnpay")),
|
||||||
url(r'^cheque/', include(cheque.urls, namespace='cheque')),
|
url(r"^cheque/", include(cheque.urls, namespace="cheque")),
|
||||||
url(r'^note_kfet/', include(note_kfet.urls, namespace='note_kfet')),
|
url(r"^note_kfet/", include(note_kfet.urls, namespace="note_kfet")),
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,19 +7,13 @@ from dateutil.relativedelta import relativedelta
|
||||||
from users.models import User
|
from users.models import User
|
||||||
from .models import Vente, Facture, Cotisation, Paiement
|
from .models import Vente, Facture, Cotisation, Paiement
|
||||||
|
|
||||||
|
|
||||||
class VenteModelTests(TestCase):
|
class VenteModelTests(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.user = User.objects.create(
|
self.user = User.objects.create(pseudo="testUser", email="test@example.org")
|
||||||
pseudo="testUser",
|
self.paiement = Paiement.objects.create(moyen="test payment")
|
||||||
email="test@example.org"
|
|
||||||
)
|
|
||||||
self.paiement = Paiement.objects.create(
|
|
||||||
moyen="test payment"
|
|
||||||
)
|
|
||||||
self.f = Facture.objects.create(
|
self.f = Facture.objects.create(
|
||||||
user=self.user,
|
user=self.user, paiement=self.paiement, valid=True
|
||||||
paiement=self.paiement,
|
|
||||||
valid=True
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_one_day_cotisation(self):
|
def test_one_day_cotisation(self):
|
||||||
|
@ -39,7 +33,7 @@ class VenteModelTests(TestCase):
|
||||||
self.assertAlmostEqual(
|
self.assertAlmostEqual(
|
||||||
self.user.end_connexion() - date,
|
self.user.end_connexion() - date,
|
||||||
datetime.timedelta(days=1),
|
datetime.timedelta(days=1),
|
||||||
delta=datetime.timedelta(seconds=1)
|
delta=datetime.timedelta(seconds=1),
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_one_month_cotisation(self):
|
def test_one_month_cotisation(self):
|
||||||
|
@ -58,10 +52,7 @@ class VenteModelTests(TestCase):
|
||||||
)
|
)
|
||||||
delta = relativedelta(self.user.end_connexion(), date)
|
delta = relativedelta(self.user.end_connexion(), date)
|
||||||
delta.microseconds = 0
|
delta.microseconds = 0
|
||||||
self.assertEqual(
|
self.assertEqual(delta, relativedelta(months=1))
|
||||||
delta,
|
|
||||||
relativedelta(months=1),
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_one_month_and_one_week_cotisation(self):
|
def test_one_month_and_one_week_cotisation(self):
|
||||||
"""
|
"""
|
||||||
|
@ -79,14 +70,9 @@ class VenteModelTests(TestCase):
|
||||||
)
|
)
|
||||||
delta = relativedelta(self.user.end_connexion(), date)
|
delta = relativedelta(self.user.end_connexion(), date)
|
||||||
delta.microseconds = 0
|
delta.microseconds = 0
|
||||||
self.assertEqual(
|
self.assertEqual(delta, relativedelta(months=1, days=7))
|
||||||
delta,
|
|
||||||
relativedelta(months=1, days=7),
|
|
||||||
)
|
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
self.f.delete()
|
self.f.delete()
|
||||||
self.user.delete()
|
self.user.delete()
|
||||||
self.paiement.delete()
|
self.paiement.delete()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ from django.utils import timezone
|
||||||
from users.models import Adherent
|
from users.models import Adherent
|
||||||
from .models import Vente, Facture, Cotisation, Paiement, Article
|
from .models import Vente, Facture, Cotisation, Paiement, Article
|
||||||
|
|
||||||
|
|
||||||
class NewFactureTests(TestCase):
|
class NewFactureTests(TestCase):
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
self.user.facture_set.all().delete()
|
self.user.facture_set.all().delete()
|
||||||
|
@ -19,51 +20,46 @@ class NewFactureTests(TestCase):
|
||||||
self.article_one_month_and_one_week.delete()
|
self.article_one_month_and_one_week.delete()
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.user = Adherent.objects.create(
|
self.user = Adherent.objects.create(pseudo="testUser", email="test@example.org")
|
||||||
pseudo="testUser",
|
self.user.set_password("plopiplop")
|
||||||
email="test@example.org",
|
|
||||||
)
|
|
||||||
self.user.set_password('plopiplop')
|
|
||||||
self.user.user_permissions.set(
|
self.user.user_permissions.set(
|
||||||
[
|
[
|
||||||
Permission.objects.get_by_natural_key("add_facture", "cotisations", "Facture"),
|
Permission.objects.get_by_natural_key(
|
||||||
Permission.objects.get_by_natural_key("use_every_payment", "cotisations", "Paiement"),
|
"add_facture", "cotisations", "Facture"
|
||||||
|
),
|
||||||
|
Permission.objects.get_by_natural_key(
|
||||||
|
"use_every_payment", "cotisations", "Paiement"
|
||||||
|
),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
self.user.save()
|
self.user.save()
|
||||||
|
|
||||||
self.paiement = Paiement.objects.create(
|
self.paiement = Paiement.objects.create(moyen="test payment")
|
||||||
moyen="test payment",
|
|
||||||
|
|
||||||
)
|
|
||||||
self.article_one_day = Article.objects.create(
|
self.article_one_day = Article.objects.create(
|
||||||
name="One day",
|
name="One day",
|
||||||
prix=0,
|
prix=0,
|
||||||
duration=0,
|
duration=0,
|
||||||
duration_days=1,
|
duration_days=1,
|
||||||
type_cotisation='All',
|
type_cotisation="All",
|
||||||
available_for_everyone=True
|
available_for_everyone=True,
|
||||||
)
|
)
|
||||||
self.article_one_month = Article.objects.create(
|
self.article_one_month = Article.objects.create(
|
||||||
name="One day",
|
name="One day",
|
||||||
prix=0,
|
prix=0,
|
||||||
duration=1,
|
duration=1,
|
||||||
duration_days=0,
|
duration_days=0,
|
||||||
type_cotisation='All',
|
type_cotisation="All",
|
||||||
available_for_everyone=True
|
available_for_everyone=True,
|
||||||
)
|
)
|
||||||
self.article_one_month_and_one_week = Article.objects.create(
|
self.article_one_month_and_one_week = Article.objects.create(
|
||||||
name="One day",
|
name="One day",
|
||||||
prix=0,
|
prix=0,
|
||||||
duration=1,
|
duration=1,
|
||||||
duration_days=7,
|
duration_days=7,
|
||||||
type_cotisation='All',
|
type_cotisation="All",
|
||||||
available_for_everyone=True
|
available_for_everyone=True,
|
||||||
)
|
|
||||||
self.client.login(
|
|
||||||
username="testUser",
|
|
||||||
password="plopiplop"
|
|
||||||
)
|
)
|
||||||
|
self.client.login(username="testUser", password="plopiplop")
|
||||||
|
|
||||||
def test_invoice_with_one_day(self):
|
def test_invoice_with_one_day(self):
|
||||||
data = {
|
data = {
|
||||||
|
@ -76,19 +72,15 @@ class NewFactureTests(TestCase):
|
||||||
"form-0-quantity": 1,
|
"form-0-quantity": 1,
|
||||||
}
|
}
|
||||||
date = timezone.now()
|
date = timezone.now()
|
||||||
response = self.client.post(reverse('cotisations:new-facture', kwargs={'userid':self.user.pk}), data)
|
response = self.client.post(
|
||||||
self.assertEqual(
|
reverse("cotisations:new-facture", kwargs={"userid": self.user.pk}), data
|
||||||
response.status_code,
|
|
||||||
302
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
response.url,
|
|
||||||
"/users/profil/%d"%self.user.pk
|
|
||||||
)
|
)
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
self.assertEqual(response.url, "/users/profil/%d" % self.user.pk)
|
||||||
self.assertAlmostEqual(
|
self.assertAlmostEqual(
|
||||||
self.user.end_connexion() - date,
|
self.user.end_connexion() - date,
|
||||||
datetime.timedelta(days=1),
|
datetime.timedelta(days=1),
|
||||||
delta=datetime.timedelta(seconds=1)
|
delta=datetime.timedelta(seconds=1),
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_invoice_with_one_month(self):
|
def test_invoice_with_one_month(self):
|
||||||
|
@ -102,21 +94,14 @@ class NewFactureTests(TestCase):
|
||||||
"form-0-quantity": 1,
|
"form-0-quantity": 1,
|
||||||
}
|
}
|
||||||
date = timezone.now()
|
date = timezone.now()
|
||||||
response = self.client.post(reverse('cotisations:new-facture', kwargs={'userid':self.user.pk}), data)
|
response = self.client.post(
|
||||||
self.assertEqual(
|
reverse("cotisations:new-facture", kwargs={"userid": self.user.pk}), data
|
||||||
response.status_code,
|
|
||||||
302
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
response.url,
|
|
||||||
"/users/profil/%d"%self.user.pk
|
|
||||||
)
|
)
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
self.assertEqual(response.url, "/users/profil/%d" % self.user.pk)
|
||||||
delta = relativedelta(self.user.end_connexion(), date)
|
delta = relativedelta(self.user.end_connexion(), date)
|
||||||
delta.microseconds = 0
|
delta.microseconds = 0
|
||||||
self.assertEqual(
|
self.assertEqual(delta, relativedelta(months=1))
|
||||||
delta,
|
|
||||||
relativedelta(months=1),
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_invoice_with_one_month_and_one_week(self):
|
def test_invoice_with_one_month_and_one_week(self):
|
||||||
data = {
|
data = {
|
||||||
|
@ -131,23 +116,15 @@ class NewFactureTests(TestCase):
|
||||||
"form-1-quantity": 1,
|
"form-1-quantity": 1,
|
||||||
}
|
}
|
||||||
date = timezone.now()
|
date = timezone.now()
|
||||||
response = self.client.post(reverse('cotisations:new-facture', kwargs={'userid':self.user.pk}), data)
|
response = self.client.post(
|
||||||
self.assertEqual(
|
reverse("cotisations:new-facture", kwargs={"userid": self.user.pk}), data
|
||||||
response.status_code,
|
|
||||||
302
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
response.url,
|
|
||||||
"/users/profil/%d"%self.user.pk
|
|
||||||
)
|
)
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
self.assertEqual(response.url, "/users/profil/%d" % self.user.pk)
|
||||||
invoice = self.user.facture_set.first()
|
invoice = self.user.facture_set.first()
|
||||||
delta = relativedelta(self.user.end_connexion(), date)
|
delta = relativedelta(self.user.end_connexion(), date)
|
||||||
delta.microseconds = 0
|
delta.microseconds = 0
|
||||||
self.assertEqual(
|
self.assertEqual(delta, relativedelta(months=1, days=7))
|
||||||
delta,
|
|
||||||
relativedelta(months=1, days=7),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_several_articles_creates_several_purchases(self):
|
def test_several_articles_creates_several_purchases(self):
|
||||||
data = {
|
data = {
|
||||||
|
@ -161,6 +138,8 @@ class NewFactureTests(TestCase):
|
||||||
"form-1-article": 2,
|
"form-1-article": 2,
|
||||||
"form-1-quantity": 1,
|
"form-1-quantity": 1,
|
||||||
}
|
}
|
||||||
response = self.client.post(reverse('cotisations:new-facture', kwargs={'userid':self.user.pk}), data)
|
response = self.client.post(
|
||||||
|
reverse("cotisations:new-facture", kwargs={"userid": self.user.pk}), data
|
||||||
|
)
|
||||||
f = self.user.facture_set.first()
|
f = self.user.facture_set.first()
|
||||||
self.assertEqual(f.vente_set.count(), 2)
|
self.assertEqual(f.vente_set.count(), 2)
|
||||||
|
|
|
@ -42,9 +42,9 @@ from re2o.mixins import AclMixin, RevMixin
|
||||||
from preferences.models import CotisationsOption
|
from preferences.models import CotisationsOption
|
||||||
|
|
||||||
|
|
||||||
TEMP_PREFIX = getattr(settings, 'TEX_TEMP_PREFIX', 'render_tex-')
|
TEMP_PREFIX = getattr(settings, "TEX_TEMP_PREFIX", "render_tex-")
|
||||||
CACHE_PREFIX = getattr(settings, 'TEX_CACHE_PREFIX', 'render-tex')
|
CACHE_PREFIX = getattr(settings, "TEX_CACHE_PREFIX", "render-tex")
|
||||||
CACHE_TIMEOUT = getattr(settings, 'TEX_CACHE_TIMEOUT', 86400) # 1 day
|
CACHE_TIMEOUT = getattr(settings, "TEX_CACHE_TIMEOUT", 86400) # 1 day
|
||||||
|
|
||||||
|
|
||||||
def render_invoice(_request, ctx={}):
|
def render_invoice(_request, ctx={}):
|
||||||
|
@ -53,20 +53,20 @@ def render_invoice(_request, ctx={}):
|
||||||
date, the user, the articles, the prices, ...
|
date, the user, the articles, the prices, ...
|
||||||
"""
|
"""
|
||||||
options, _ = CotisationsOption.objects.get_or_create()
|
options, _ = CotisationsOption.objects.get_or_create()
|
||||||
is_estimate = ctx.get('is_estimate', False)
|
is_estimate = ctx.get("is_estimate", False)
|
||||||
filename = '_'.join([
|
filename = "_".join(
|
||||||
'cost_estimate' if is_estimate else 'invoice',
|
[
|
||||||
slugify(ctx.get('asso_name', "")),
|
"cost_estimate" if is_estimate else "invoice",
|
||||||
slugify(ctx.get('recipient_name', "")),
|
slugify(ctx.get("asso_name", "")),
|
||||||
str(ctx.get('DATE', datetime.now()).year),
|
slugify(ctx.get("recipient_name", "")),
|
||||||
str(ctx.get('DATE', datetime.now()).month),
|
str(ctx.get("DATE", datetime.now()).year),
|
||||||
str(ctx.get('DATE', datetime.now()).day),
|
str(ctx.get("DATE", datetime.now()).month),
|
||||||
])
|
str(ctx.get("DATE", datetime.now()).day),
|
||||||
templatename = options.invoice_template.template.name.split('/')[-1]
|
]
|
||||||
r = render_tex(_request, templatename, ctx)
|
|
||||||
r['Content-Disposition'] = 'attachment; filename="{name}.pdf"'.format(
|
|
||||||
name=filename
|
|
||||||
)
|
)
|
||||||
|
templatename = options.invoice_template.template.name.split("/")[-1]
|
||||||
|
r = render_tex(_request, templatename, ctx)
|
||||||
|
r["Content-Disposition"] = 'attachment; filename="{name}.pdf"'.format(name=filename)
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
|
||||||
|
@ -75,20 +75,20 @@ def render_voucher(_request, ctx={}):
|
||||||
Render a subscribtion voucher.
|
Render a subscribtion voucher.
|
||||||
"""
|
"""
|
||||||
options, _ = CotisationsOption.objects.get_or_create()
|
options, _ = CotisationsOption.objects.get_or_create()
|
||||||
filename = '_'.join([
|
filename = "_".join(
|
||||||
'voucher',
|
[
|
||||||
slugify(ctx.get('asso_name', "")),
|
"voucher",
|
||||||
slugify(ctx.get('firstname', "")),
|
slugify(ctx.get("asso_name", "")),
|
||||||
slugify(ctx.get('lastname', "")),
|
slugify(ctx.get("firstname", "")),
|
||||||
str(ctx.get('date_begin', datetime.now()).year),
|
slugify(ctx.get("lastname", "")),
|
||||||
str(ctx.get('date_begin', datetime.now()).month),
|
str(ctx.get("date_begin", datetime.now()).year),
|
||||||
str(ctx.get('date_begin', datetime.now()).day),
|
str(ctx.get("date_begin", datetime.now()).month),
|
||||||
])
|
str(ctx.get("date_begin", datetime.now()).day),
|
||||||
templatename = options.voucher_template.template.name.split('/')[-1]
|
]
|
||||||
r = render_tex(_request, templatename, ctx)
|
|
||||||
r['Content-Disposition'] = 'attachment; filename="{name}.pdf"'.format(
|
|
||||||
name=filename
|
|
||||||
)
|
)
|
||||||
|
templatename = options.voucher_template.template.name.split("/")[-1]
|
||||||
|
r = render_tex(_request, templatename, ctx)
|
||||||
|
r["Content-Disposition"] = 'attachment; filename="{name}.pdf"'.format(name=filename)
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
|
||||||
|
@ -106,18 +106,18 @@ def create_pdf(template, ctx={}):
|
||||||
"""
|
"""
|
||||||
context = ctx
|
context = ctx
|
||||||
template = get_template(template)
|
template = get_template(template)
|
||||||
rendered_tpl = template.render(context).encode('utf-8')
|
rendered_tpl = template.render(context).encode("utf-8")
|
||||||
|
|
||||||
with tempfile.TemporaryDirectory() as tempdir:
|
with tempfile.TemporaryDirectory() as tempdir:
|
||||||
for _ in range(2):
|
for _ in range(2):
|
||||||
with open("/var/www/re2o/out.log", "w") as f:
|
with open("/var/www/re2o/out.log", "w") as f:
|
||||||
process = Popen(
|
process = Popen(
|
||||||
['pdflatex', '-output-directory', tempdir],
|
["pdflatex", "-output-directory", tempdir],
|
||||||
stdin=PIPE,
|
stdin=PIPE,
|
||||||
stdout=f, # PIPE,
|
stdout=f, # PIPE,
|
||||||
)
|
)
|
||||||
process.communicate(rendered_tpl)
|
process.communicate(rendered_tpl)
|
||||||
with open(os.path.join(tempdir, 'texput.pdf'), 'rb') as f:
|
with open(os.path.join(tempdir, "texput.pdf"), "rb") as f:
|
||||||
pdf = f.read()
|
pdf = f.read()
|
||||||
|
|
||||||
return pdf
|
return pdf
|
||||||
|
@ -127,10 +127,7 @@ def escape_chars(string):
|
||||||
"""Escape the '%' and the '€' signs to avoid messing with LaTeX"""
|
"""Escape the '%' and the '€' signs to avoid messing with LaTeX"""
|
||||||
if not isinstance(string, str):
|
if not isinstance(string, str):
|
||||||
return string
|
return string
|
||||||
mapping = (
|
mapping = (("€", r"\euro"), ("%", r"\%"))
|
||||||
('€', r'\euro'),
|
|
||||||
('%', r'\%'),
|
|
||||||
)
|
|
||||||
r = str(string)
|
r = str(string)
|
||||||
for k, v in mapping:
|
for k, v in mapping:
|
||||||
r = r.replace(k, v)
|
r = r.replace(k, v)
|
||||||
|
@ -152,6 +149,6 @@ def render_tex(_request, template, ctx={}):
|
||||||
An HttpResponse with type `application/pdf` containing the PDF file.
|
An HttpResponse with type `application/pdf` containing the PDF file.
|
||||||
"""
|
"""
|
||||||
pdf = create_pdf(template, ctx)
|
pdf = create_pdf(template, ctx)
|
||||||
r = HttpResponse(content_type='application/pdf')
|
r = HttpResponse(content_type="application/pdf")
|
||||||
r.write(pdf)
|
r.write(pdf)
|
||||||
return r
|
return r
|
||||||
|
|
|
@ -31,155 +31,77 @@ from . import views
|
||||||
from . import payment_methods
|
from . import payment_methods
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
url(r"^new_facture/(?P<userid>[0-9]+)$", views.new_facture, name="new-facture"),
|
||||||
url(
|
url(
|
||||||
r'^new_facture/(?P<userid>[0-9]+)$',
|
r"^edit_facture/(?P<factureid>[0-9]+)$", views.edit_facture, name="edit-facture"
|
||||||
views.new_facture,
|
),
|
||||||
name='new-facture'
|
url(r"^del_facture/(?P<factureid>[0-9]+)$", views.del_facture, name="del-facture"),
|
||||||
|
url(r"^facture_pdf/(?P<factureid>[0-9]+)$", views.facture_pdf, name="facture-pdf"),
|
||||||
|
url(r"^voucher_pdf/(?P<factureid>[0-9]+)$", views.voucher_pdf, name="voucher-pdf"),
|
||||||
|
url(r"^new_cost_estimate/$", views.new_cost_estimate, name="new-cost-estimate"),
|
||||||
|
url(
|
||||||
|
r"^index_cost_estimate/$", views.index_cost_estimate, name="index-cost-estimate"
|
||||||
),
|
),
|
||||||
url(
|
url(
|
||||||
r'^edit_facture/(?P<factureid>[0-9]+)$',
|
r"^cost_estimate_pdf/(?P<costestimateid>[0-9]+)$",
|
||||||
views.edit_facture,
|
|
||||||
name='edit-facture'
|
|
||||||
),
|
|
||||||
url(
|
|
||||||
r'^del_facture/(?P<factureid>[0-9]+)$',
|
|
||||||
views.del_facture,
|
|
||||||
name='del-facture'
|
|
||||||
),
|
|
||||||
url(
|
|
||||||
r'^facture_pdf/(?P<factureid>[0-9]+)$',
|
|
||||||
views.facture_pdf,
|
|
||||||
name='facture-pdf'
|
|
||||||
),
|
|
||||||
url(
|
|
||||||
r'^voucher_pdf/(?P<factureid>[0-9]+)$',
|
|
||||||
views.voucher_pdf,
|
|
||||||
name='voucher-pdf'
|
|
||||||
),
|
|
||||||
url(
|
|
||||||
r'^new_cost_estimate/$',
|
|
||||||
views.new_cost_estimate,
|
|
||||||
name='new-cost-estimate'
|
|
||||||
),
|
|
||||||
url(
|
|
||||||
r'^index_cost_estimate/$',
|
|
||||||
views.index_cost_estimate,
|
|
||||||
name='index-cost-estimate'
|
|
||||||
),
|
|
||||||
url(
|
|
||||||
r'^cost_estimate_pdf/(?P<costestimateid>[0-9]+)$',
|
|
||||||
views.cost_estimate_pdf,
|
views.cost_estimate_pdf,
|
||||||
name='cost-estimate-pdf',
|
name="cost-estimate-pdf",
|
||||||
),
|
),
|
||||||
url(
|
url(
|
||||||
r'^index_custom_invoice/$',
|
r"^index_custom_invoice/$",
|
||||||
views.index_custom_invoice,
|
views.index_custom_invoice,
|
||||||
name='index-custom-invoice'
|
name="index-custom-invoice",
|
||||||
),
|
),
|
||||||
url(
|
url(
|
||||||
r'^edit_cost_estimate/(?P<costestimateid>[0-9]+)$',
|
r"^edit_cost_estimate/(?P<costestimateid>[0-9]+)$",
|
||||||
views.edit_cost_estimate,
|
views.edit_cost_estimate,
|
||||||
name='edit-cost-estimate'
|
name="edit-cost-estimate",
|
||||||
),
|
),
|
||||||
url(
|
url(
|
||||||
r'^cost_estimate_to_invoice/(?P<costestimateid>[0-9]+)$',
|
r"^cost_estimate_to_invoice/(?P<costestimateid>[0-9]+)$",
|
||||||
views.cost_estimate_to_invoice,
|
views.cost_estimate_to_invoice,
|
||||||
name='cost-estimate-to-invoice'
|
name="cost-estimate-to-invoice",
|
||||||
),
|
),
|
||||||
url(
|
url(
|
||||||
r'^del_cost_estimate/(?P<costestimateid>[0-9]+)$',
|
r"^del_cost_estimate/(?P<costestimateid>[0-9]+)$",
|
||||||
views.del_cost_estimate,
|
views.del_cost_estimate,
|
||||||
name='del-cost-estimate'
|
name="del-cost-estimate",
|
||||||
),
|
),
|
||||||
|
url(r"^new_custom_invoice/$", views.new_custom_invoice, name="new-custom-invoice"),
|
||||||
url(
|
url(
|
||||||
r'^new_custom_invoice/$',
|
r"^edit_custom_invoice/(?P<custominvoiceid>[0-9]+)$",
|
||||||
views.new_custom_invoice,
|
|
||||||
name='new-custom-invoice'
|
|
||||||
),
|
|
||||||
url(
|
|
||||||
r'^edit_custom_invoice/(?P<custominvoiceid>[0-9]+)$',
|
|
||||||
views.edit_custom_invoice,
|
views.edit_custom_invoice,
|
||||||
name='edit-custom-invoice'
|
name="edit-custom-invoice",
|
||||||
),
|
),
|
||||||
url(
|
url(
|
||||||
r'^custom_invoice_pdf/(?P<custominvoiceid>[0-9]+)$',
|
r"^custom_invoice_pdf/(?P<custominvoiceid>[0-9]+)$",
|
||||||
views.custom_invoice_pdf,
|
views.custom_invoice_pdf,
|
||||||
name='custom-invoice-pdf',
|
name="custom-invoice-pdf",
|
||||||
),
|
),
|
||||||
url(
|
url(
|
||||||
r'^del_custom_invoice/(?P<custominvoiceid>[0-9]+)$',
|
r"^del_custom_invoice/(?P<custominvoiceid>[0-9]+)$",
|
||||||
views.del_custom_invoice,
|
views.del_custom_invoice,
|
||||||
name='del-custom-invoice'
|
name="del-custom-invoice",
|
||||||
),
|
),
|
||||||
|
url(r"^credit_solde/(?P<userid>[0-9]+)$", views.credit_solde, name="credit-solde"),
|
||||||
|
url(r"^add_article/$", views.add_article, name="add-article"),
|
||||||
url(
|
url(
|
||||||
r'^credit_solde/(?P<userid>[0-9]+)$',
|
r"^edit_article/(?P<articleid>[0-9]+)$", views.edit_article, name="edit-article"
|
||||||
views.credit_solde,
|
|
||||||
name='credit-solde'
|
|
||||||
),
|
),
|
||||||
|
url(r"^del_article/$", views.del_article, name="del-article"),
|
||||||
|
url(r"^add_paiement/$", views.add_paiement, name="add-paiement"),
|
||||||
url(
|
url(
|
||||||
r'^add_article/$',
|
r"^edit_paiement/(?P<paiementid>[0-9]+)$",
|
||||||
views.add_article,
|
|
||||||
name='add-article'
|
|
||||||
),
|
|
||||||
url(
|
|
||||||
r'^edit_article/(?P<articleid>[0-9]+)$',
|
|
||||||
views.edit_article,
|
|
||||||
name='edit-article'
|
|
||||||
),
|
|
||||||
url(
|
|
||||||
r'^del_article/$',
|
|
||||||
views.del_article,
|
|
||||||
name='del-article'
|
|
||||||
),
|
|
||||||
url(
|
|
||||||
r'^add_paiement/$',
|
|
||||||
views.add_paiement,
|
|
||||||
name='add-paiement'
|
|
||||||
),
|
|
||||||
url(
|
|
||||||
r'^edit_paiement/(?P<paiementid>[0-9]+)$',
|
|
||||||
views.edit_paiement,
|
views.edit_paiement,
|
||||||
name='edit-paiement'
|
name="edit-paiement",
|
||||||
),
|
),
|
||||||
url(
|
url(r"^del_paiement/$", views.del_paiement, name="del-paiement"),
|
||||||
r'^del_paiement/$',
|
url(r"^add_banque/$", views.add_banque, name="add-banque"),
|
||||||
views.del_paiement,
|
url(r"^edit_banque/(?P<banqueid>[0-9]+)$", views.edit_banque, name="edit-banque"),
|
||||||
name='del-paiement'
|
url(r"^del_banque/$", views.del_banque, name="del-banque"),
|
||||||
),
|
url(r"^index_article/$", views.index_article, name="index-article"),
|
||||||
url(
|
url(r"^index_banque/$", views.index_banque, name="index-banque"),
|
||||||
r'^add_banque/$',
|
url(r"^index_paiement/$", views.index_paiement, name="index-paiement"),
|
||||||
views.add_banque,
|
url(r"^control/$", views.control, name="control"),
|
||||||
name='add-banque'
|
url(r"^$", views.index, name="index"),
|
||||||
),
|
|
||||||
url(
|
|
||||||
r'^edit_banque/(?P<banqueid>[0-9]+)$',
|
|
||||||
views.edit_banque,
|
|
||||||
name='edit-banque'
|
|
||||||
),
|
|
||||||
url(
|
|
||||||
r'^del_banque/$',
|
|
||||||
views.del_banque,
|
|
||||||
name='del-banque'
|
|
||||||
),
|
|
||||||
url(
|
|
||||||
r'^index_article/$',
|
|
||||||
views.index_article,
|
|
||||||
name='index-article'
|
|
||||||
),
|
|
||||||
url(
|
|
||||||
r'^index_banque/$',
|
|
||||||
views.index_banque,
|
|
||||||
name='index-banque'
|
|
||||||
),
|
|
||||||
url(
|
|
||||||
r'^index_paiement/$',
|
|
||||||
views.index_paiement,
|
|
||||||
name='index-paiement'
|
|
||||||
),
|
|
||||||
url(
|
|
||||||
r'^control/$',
|
|
||||||
views.control,
|
|
||||||
name='control'
|
|
||||||
),
|
|
||||||
url(r'^$', views.index, name='index'),
|
|
||||||
] + payment_methods.urls.urlpatterns
|
] + payment_methods.urls.urlpatterns
|
||||||
|
|
|
@ -25,9 +25,7 @@ from django.template.loader import get_template
|
||||||
from django.core.mail import EmailMessage
|
from django.core.mail import EmailMessage
|
||||||
|
|
||||||
from .tex import create_pdf
|
from .tex import create_pdf
|
||||||
from preferences.models import (
|
from preferences.models import AssoOption, GeneralOption, CotisationsOption, Mandate
|
||||||
AssoOption, GeneralOption, CotisationsOption, Mandate
|
|
||||||
)
|
|
||||||
from re2o.settings import LOGO_PATH
|
from re2o.settings import LOGO_PATH
|
||||||
from re2o import settings
|
from re2o import settings
|
||||||
|
|
||||||
|
@ -35,6 +33,7 @@ from re2o import settings
|
||||||
def find_payment_method(payment):
|
def find_payment_method(payment):
|
||||||
"""Finds the payment method associated to the payment if it exists."""
|
"""Finds the payment method associated to the payment if it exists."""
|
||||||
from cotisations.payment_methods import PAYMENT_METHODS
|
from cotisations.payment_methods import PAYMENT_METHODS
|
||||||
|
|
||||||
for method in PAYMENT_METHODS:
|
for method in PAYMENT_METHODS:
|
||||||
try:
|
try:
|
||||||
o = method.PaymentMethod.objects.get(payment=payment)
|
o = method.PaymentMethod.objects.get(payment=payment)
|
||||||
|
@ -48,51 +47,47 @@ def send_mail_invoice(invoice):
|
||||||
"""Creates the pdf of the invoice and sends it by email to the client"""
|
"""Creates the pdf of the invoice and sends it by email to the client"""
|
||||||
purchases_info = []
|
purchases_info = []
|
||||||
for purchase in invoice.vente_set.all():
|
for purchase in invoice.vente_set.all():
|
||||||
purchases_info.append({
|
purchases_info.append(
|
||||||
'name': purchase.name,
|
{
|
||||||
'price': purchase.prix,
|
"name": purchase.name,
|
||||||
'quantity': purchase.number,
|
"price": purchase.prix,
|
||||||
'total_price': purchase.prix_total
|
"quantity": purchase.number,
|
||||||
})
|
"total_price": purchase.prix_total,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
ctx = {
|
ctx = {
|
||||||
'paid': True,
|
"paid": True,
|
||||||
'fid': invoice.id,
|
"fid": invoice.id,
|
||||||
'DATE': invoice.date,
|
"DATE": invoice.date,
|
||||||
'recipient_name': "{} {}".format(
|
"recipient_name": "{} {}".format(invoice.user.name, invoice.user.surname),
|
||||||
invoice.user.name,
|
"address": invoice.user.room,
|
||||||
invoice.user.surname
|
"article": purchases_info,
|
||||||
),
|
"total": invoice.prix_total(),
|
||||||
'address': invoice.user.room,
|
"asso_name": AssoOption.get_cached_value("name"),
|
||||||
'article': purchases_info,
|
"line1": AssoOption.get_cached_value("adresse1"),
|
||||||
'total': invoice.prix_total(),
|
"line2": AssoOption.get_cached_value("adresse2"),
|
||||||
'asso_name': AssoOption.get_cached_value('name'),
|
"siret": AssoOption.get_cached_value("siret"),
|
||||||
'line1': AssoOption.get_cached_value('adresse1'),
|
"email": AssoOption.get_cached_value("contact"),
|
||||||
'line2': AssoOption.get_cached_value('adresse2'),
|
"phone": AssoOption.get_cached_value("telephone"),
|
||||||
'siret': AssoOption.get_cached_value('siret'),
|
"tpl_path": os.path.join(settings.BASE_DIR, LOGO_PATH),
|
||||||
'email': AssoOption.get_cached_value('contact'),
|
|
||||||
'phone': AssoOption.get_cached_value('telephone'),
|
|
||||||
'tpl_path': os.path.join(settings.BASE_DIR, LOGO_PATH)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pdf = create_pdf('cotisations/factures.tex', ctx)
|
pdf = create_pdf("cotisations/factures.tex", ctx)
|
||||||
template = get_template('cotisations/email_invoice')
|
template = get_template("cotisations/email_invoice")
|
||||||
|
|
||||||
ctx = {
|
ctx = {
|
||||||
'name': "{} {}".format(
|
"name": "{} {}".format(invoice.user.name, invoice.user.surname),
|
||||||
invoice.user.name,
|
"contact_mail": AssoOption.get_cached_value("contact"),
|
||||||
invoice.user.surname
|
"asso_name": AssoOption.get_cached_value("name"),
|
||||||
),
|
|
||||||
'contact_mail': AssoOption.get_cached_value('contact'),
|
|
||||||
'asso_name': AssoOption.get_cached_value('name')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mail = EmailMessage(
|
mail = EmailMessage(
|
||||||
'Votre facture / Your invoice',
|
"Votre facture / Your invoice",
|
||||||
template.render(ctx),
|
template.render(ctx),
|
||||||
GeneralOption.get_cached_value('email_from'),
|
GeneralOption.get_cached_value("email_from"),
|
||||||
[invoice.user.get_mail],
|
[invoice.user.get_mail],
|
||||||
attachments=[('invoice.pdf', pdf, 'application/pdf')]
|
attachments=[("invoice.pdf", pdf, "application/pdf")],
|
||||||
)
|
)
|
||||||
mail.send()
|
mail.send()
|
||||||
|
|
||||||
|
@ -101,34 +96,33 @@ def send_mail_voucher(invoice):
|
||||||
"""Creates a voucher from an invoice and sends it by email to the client"""
|
"""Creates a voucher from an invoice and sends it by email to the client"""
|
||||||
president = Mandate.get_mandate(invoice.date).president
|
president = Mandate.get_mandate(invoice.date).president
|
||||||
ctx = {
|
ctx = {
|
||||||
'asso_name': AssoOption.get_cached_value('name'),
|
"asso_name": AssoOption.get_cached_value("name"),
|
||||||
'pres_name': ' '.join([president.name, president.surname]),
|
"pres_name": " ".join([president.name, president.surname]),
|
||||||
'firstname': invoice.user.name,
|
"firstname": invoice.user.name,
|
||||||
'lastname': invoice.user.surname,
|
"lastname": invoice.user.surname,
|
||||||
'email': invoice.user.email,
|
"email": invoice.user.email,
|
||||||
'phone': invoice.user.telephone,
|
"phone": invoice.user.telephone,
|
||||||
'date_end': invoice.get_subscription().latest('date_end').date_end,
|
"date_end": invoice.get_subscription().latest("date_end").date_end,
|
||||||
'date_begin': invoice.get_subscription().earliest('date_start').date_start
|
"date_begin": invoice.get_subscription().earliest("date_start").date_start,
|
||||||
}
|
}
|
||||||
templatename = CotisationsOption.get_cached_value('voucher_template').template.name.split('/')[-1]
|
templatename = CotisationsOption.get_cached_value(
|
||||||
|
"voucher_template"
|
||||||
|
).template.name.split("/")[-1]
|
||||||
pdf = create_pdf(templatename, ctx)
|
pdf = create_pdf(templatename, ctx)
|
||||||
template = get_template('cotisations/email_subscription_accepted')
|
template = get_template("cotisations/email_subscription_accepted")
|
||||||
|
|
||||||
ctx = {
|
ctx = {
|
||||||
'name': "{} {}".format(
|
"name": "{} {}".format(invoice.user.name, invoice.user.surname),
|
||||||
invoice.user.name,
|
"asso_email": AssoOption.get_cached_value("contact"),
|
||||||
invoice.user.surname
|
"asso_name": AssoOption.get_cached_value("name"),
|
||||||
),
|
"date_end": invoice.get_subscription().latest("date_end").date_end,
|
||||||
'asso_email': AssoOption.get_cached_value('contact'),
|
|
||||||
'asso_name': AssoOption.get_cached_value('name'),
|
|
||||||
'date_end': invoice.get_subscription().latest('date_end').date_end,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mail = EmailMessage(
|
mail = EmailMessage(
|
||||||
'Votre reçu / Your voucher',
|
"Votre reçu / Your voucher",
|
||||||
template.render(ctx),
|
template.render(ctx),
|
||||||
GeneralOption.get_cached_value('email_from'),
|
GeneralOption.get_cached_value("email_from"),
|
||||||
[invoice.user.get_mail],
|
[invoice.user.get_mail],
|
||||||
attachments=[('voucher.pdf', pdf, 'application/pdf')]
|
attachments=[("voucher.pdf", pdf, "application/pdf")],
|
||||||
)
|
)
|
||||||
mail.send()
|
mail.send()
|
||||||
|
|
|
@ -12,11 +12,9 @@ def check_no_balance(is_balance):
|
||||||
ValidationError: if such a Paiement exists.
|
ValidationError: if such a Paiement exists.
|
||||||
"""
|
"""
|
||||||
from .models import Paiement
|
from .models import Paiement
|
||||||
|
|
||||||
if not is_balance:
|
if not is_balance:
|
||||||
return
|
return
|
||||||
p = Paiement.objects.filter(is_balance=True)
|
p = Paiement.objects.filter(is_balance=True)
|
||||||
if len(p) > 0:
|
if len(p) > 0:
|
||||||
raise ValidationError(
|
raise ValidationError(_("There is already a payment method for user balance."))
|
||||||
_("There is already a payment method for user balance.")
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -62,7 +62,7 @@ from preferences.models import RadiusOption
|
||||||
|
|
||||||
|
|
||||||
#: Serveur radius de test (pas la prod)
|
#: Serveur radius de test (pas la prod)
|
||||||
TEST_SERVER = bool(os.getenv('DBG_FREERADIUS', False))
|
TEST_SERVER = bool(os.getenv("DBG_FREERADIUS", False))
|
||||||
|
|
||||||
|
|
||||||
# Logging
|
# Logging
|
||||||
|
@ -77,13 +77,13 @@ class RadiusdHandler(logging.Handler):
|
||||||
rad_sig = radiusd.L_INFO
|
rad_sig = radiusd.L_INFO
|
||||||
else:
|
else:
|
||||||
rad_sig = radiusd.L_DBG
|
rad_sig = radiusd.L_DBG
|
||||||
radiusd.radlog(rad_sig, record.msg.encode('utf-8'))
|
radiusd.radlog(rad_sig, record.msg.encode("utf-8"))
|
||||||
|
|
||||||
|
|
||||||
# Initialisation d'un logger (pour logguer unifié)
|
# Initialisation d'un logger (pour logguer unifié)
|
||||||
logger = logging.getLogger('auth.py')
|
logger = logging.getLogger("auth.py")
|
||||||
logger.setLevel(logging.DEBUG)
|
logger.setLevel(logging.DEBUG)
|
||||||
formatter = logging.Formatter('%(name)s: [%(levelname)s] %(message)s')
|
formatter = logging.Formatter("%(name)s: [%(levelname)s] %(message)s")
|
||||||
handler = RadiusdHandler()
|
handler = RadiusdHandler()
|
||||||
handler.setFormatter(formatter)
|
handler.setFormatter(formatter)
|
||||||
logger.addHandler(handler)
|
logger.addHandler(handler)
|
||||||
|
@ -111,17 +111,16 @@ def radius_event(fun):
|
||||||
for (key, value) in auth_data or []:
|
for (key, value) in auth_data or []:
|
||||||
# Beware: les valeurs scalaires sont entre guillemets
|
# Beware: les valeurs scalaires sont entre guillemets
|
||||||
# Ex: Calling-Station-Id: "une_adresse_mac"
|
# Ex: Calling-Station-Id: "une_adresse_mac"
|
||||||
data[key] = value.replace('"', '')
|
data[key] = value.replace('"', "")
|
||||||
try:
|
try:
|
||||||
# TODO s'assurer ici que les tuples renvoyés sont bien des
|
# TODO s'assurer ici que les tuples renvoyés sont bien des
|
||||||
# (str,str) : rlm_python ne digère PAS les unicodes
|
# (str,str) : rlm_python ne digère PAS les unicodes
|
||||||
return fun(data)
|
return fun(data)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
exc_type, exc_instance, exc_traceback = sys.exc_info()
|
exc_type, exc_instance, exc_traceback = sys.exc_info()
|
||||||
formatted_traceback = ''.join(traceback.format_tb(
|
formatted_traceback = "".join(traceback.format_tb(exc_traceback))
|
||||||
exc_traceback))
|
logger.error("Failed %r on data %r" % (err, auth_data))
|
||||||
logger.error('Failed %r on data %r' % (err, auth_data))
|
logger.error("Function %r, Traceback : %r" % (fun, formatted_traceback))
|
||||||
logger.error('Function %r, Traceback : %r' % (fun, formatted_traceback))
|
|
||||||
return radiusd.RLM_MODULE_FAIL
|
return radiusd.RLM_MODULE_FAIL
|
||||||
|
|
||||||
return new_f
|
return new_f
|
||||||
|
@ -131,9 +130,9 @@ def radius_event(fun):
|
||||||
def instantiate(*_):
|
def instantiate(*_):
|
||||||
"""Utile pour initialiser les connexions ldap une première fois (otherwise,
|
"""Utile pour initialiser les connexions ldap une première fois (otherwise,
|
||||||
do nothing)"""
|
do nothing)"""
|
||||||
logger.info('Instantiation')
|
logger.info("Instantiation")
|
||||||
if TEST_SERVER:
|
if TEST_SERVER:
|
||||||
logger.info(u'DBG_FREERADIUS is enabled')
|
logger.info(u"DBG_FREERADIUS is enabled")
|
||||||
|
|
||||||
|
|
||||||
@radius_event
|
@radius_event
|
||||||
|
@ -146,23 +145,19 @@ def authorize(data):
|
||||||
accept en authorize
|
accept en authorize
|
||||||
"""
|
"""
|
||||||
# Pour les requetes proxifiees, on split
|
# Pour les requetes proxifiees, on split
|
||||||
nas = data.get('NAS-IP-Address', data.get('NAS-Identifier', None))
|
nas = data.get("NAS-IP-Address", data.get("NAS-Identifier", None))
|
||||||
nas_instance = find_nas_from_request(nas)
|
nas_instance = find_nas_from_request(nas)
|
||||||
# Toutes les reuquètes non proxifiées
|
# Toutes les reuquètes non proxifiées
|
||||||
nas_type = None
|
nas_type = None
|
||||||
if nas_instance:
|
if nas_instance:
|
||||||
nas_type = Nas.objects.filter(nas_type=nas_instance.machine_type).first()
|
nas_type = Nas.objects.filter(nas_type=nas_instance.machine_type).first()
|
||||||
if not nas_type or nas_type.port_access_mode == '802.1X':
|
if not nas_type or nas_type.port_access_mode == "802.1X":
|
||||||
user = data.get('User-Name', '').decode('utf-8', errors='replace')
|
user = data.get("User-Name", "").decode("utf-8", errors="replace")
|
||||||
user = user.split('@', 1)[0]
|
user = user.split("@", 1)[0]
|
||||||
mac = data.get('Calling-Station-Id', '')
|
mac = data.get("Calling-Station-Id", "")
|
||||||
result, log, password = check_user_machine_and_register(
|
result, log, password = check_user_machine_and_register(nas_type, user, mac)
|
||||||
nas_type,
|
logger.info(log.encode("utf-8"))
|
||||||
user,
|
logger.info(user.encode("utf-8"))
|
||||||
mac
|
|
||||||
)
|
|
||||||
logger.info(log.encode('utf-8'))
|
|
||||||
logger.info(user.encode('utf-8'))
|
|
||||||
|
|
||||||
if not result:
|
if not result:
|
||||||
return radiusd.RLM_MODULE_REJECT
|
return radiusd.RLM_MODULE_REJECT
|
||||||
|
@ -170,19 +165,11 @@ def authorize(data):
|
||||||
return (
|
return (
|
||||||
radiusd.RLM_MODULE_UPDATED,
|
radiusd.RLM_MODULE_UPDATED,
|
||||||
(),
|
(),
|
||||||
(
|
((str("NT-Password"), str(password)),),
|
||||||
(str("NT-Password"), str(password)),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return (
|
return (radiusd.RLM_MODULE_UPDATED, (), (("Auth-Type", "Accept"),))
|
||||||
radiusd.RLM_MODULE_UPDATED,
|
|
||||||
(),
|
|
||||||
(
|
|
||||||
("Auth-Type", "Accept"),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@radius_event
|
@radius_event
|
||||||
|
@ -190,52 +177,49 @@ def post_auth(data):
|
||||||
""" Function called after the user is authenticated
|
""" Function called after the user is authenticated
|
||||||
"""
|
"""
|
||||||
|
|
||||||
nas = data.get('NAS-IP-Address', data.get('NAS-Identifier', None))
|
nas = data.get("NAS-IP-Address", data.get("NAS-Identifier", None))
|
||||||
nas_instance = find_nas_from_request(nas)
|
nas_instance = find_nas_from_request(nas)
|
||||||
# Toutes les reuquètes non proxifiées
|
# Toutes les reuquètes non proxifiées
|
||||||
if not nas_instance:
|
if not nas_instance:
|
||||||
logger.info(u"Requete proxifiee, nas inconnu".encode('utf-8'))
|
logger.info(u"Requete proxifiee, nas inconnu".encode("utf-8"))
|
||||||
return radiusd.RLM_MODULE_OK
|
return radiusd.RLM_MODULE_OK
|
||||||
nas_type = Nas.objects.filter(nas_type=nas_instance.machine_type).first()
|
nas_type = Nas.objects.filter(nas_type=nas_instance.machine_type).first()
|
||||||
if not nas_type:
|
if not nas_type:
|
||||||
logger.info(
|
logger.info(u"Type de nas non enregistre dans la bdd!".encode("utf-8"))
|
||||||
u"Type de nas non enregistre dans la bdd!".encode('utf-8')
|
|
||||||
)
|
|
||||||
return radiusd.RLM_MODULE_OK
|
return radiusd.RLM_MODULE_OK
|
||||||
|
|
||||||
mac = data.get('Calling-Station-Id', None)
|
mac = data.get("Calling-Station-Id", None)
|
||||||
|
|
||||||
# Switch et bornes héritent de machine et peuvent avoir plusieurs
|
# Switch et bornes héritent de machine et peuvent avoir plusieurs
|
||||||
# interfaces filles
|
# interfaces filles
|
||||||
nas_machine = nas_instance.machine
|
nas_machine = nas_instance.machine
|
||||||
# Si il s'agit d'un switch
|
# Si il s'agit d'un switch
|
||||||
if hasattr(nas_machine, 'switch'):
|
if hasattr(nas_machine, "switch"):
|
||||||
port = data.get('NAS-Port-Id', data.get('NAS-Port', None))
|
port = data.get("NAS-Port-Id", data.get("NAS-Port", None))
|
||||||
# Pour les infrastructures possédant des switchs Juniper :
|
# Pour les infrastructures possédant des switchs Juniper :
|
||||||
# On vérifie si le switch fait partie d'un stack Juniper
|
# On vérifie si le switch fait partie d'un stack Juniper
|
||||||
instance_stack = nas_machine.switch.stack
|
instance_stack = nas_machine.switch.stack
|
||||||
if instance_stack:
|
if instance_stack:
|
||||||
# Si c'est le cas, on resélectionne le bon switch dans la stack
|
# Si c'est le cas, on resélectionne le bon switch dans la stack
|
||||||
id_stack_member = port.split("-")[1].split('/')[0]
|
id_stack_member = port.split("-")[1].split("/")[0]
|
||||||
nas_machine = (Switch.objects
|
nas_machine = (
|
||||||
.filter(stack=instance_stack)
|
Switch.objects.filter(stack=instance_stack)
|
||||||
.filter(stack_member_id=id_stack_member)
|
.filter(stack_member_id=id_stack_member)
|
||||||
.prefetch_related(
|
.prefetch_related("interface_set__domain__extension")
|
||||||
'interface_set__domain__extension'
|
.first()
|
||||||
)
|
)
|
||||||
.first())
|
|
||||||
# On récupère le numéro du port sur l'output de freeradius.
|
# On récupère le numéro du port sur l'output de freeradius.
|
||||||
# La ligne suivante fonctionne pour cisco, HP et Juniper
|
# La ligne suivante fonctionne pour cisco, HP et Juniper
|
||||||
port = port.split(".")[0].split('/')[-1][-2:]
|
port = port.split(".")[0].split("/")[-1][-2:]
|
||||||
out = decide_vlan_switch(nas_machine, nas_type, port, mac)
|
out = decide_vlan_switch(nas_machine, nas_type, port, mac)
|
||||||
sw_name, room, reason, vlan_id, decision, attributes = out
|
sw_name, room, reason, vlan_id, decision, attributes = out
|
||||||
|
|
||||||
if decision:
|
if decision:
|
||||||
log_message = '(fil) %s -> %s [%s%s]' % (
|
log_message = "(fil) %s -> %s [%s%s]" % (
|
||||||
sw_name + u":" + port + u"/" + str(room),
|
sw_name + u":" + port + u"/" + str(room),
|
||||||
mac,
|
mac,
|
||||||
vlan_id,
|
vlan_id,
|
||||||
(reason and u': ' + reason).encode('utf-8')
|
(reason and u": " + reason).encode("utf-8"),
|
||||||
)
|
)
|
||||||
logger.info(log_message)
|
logger.info(log_message)
|
||||||
|
|
||||||
|
@ -245,23 +229,20 @@ def post_auth(data):
|
||||||
(
|
(
|
||||||
("Tunnel-Type", "VLAN"),
|
("Tunnel-Type", "VLAN"),
|
||||||
("Tunnel-Medium-Type", "IEEE-802"),
|
("Tunnel-Medium-Type", "IEEE-802"),
|
||||||
("Tunnel-Private-Group-Id", '%d' % int(vlan_id)),
|
("Tunnel-Private-Group-Id", "%d" % int(vlan_id)),
|
||||||
) + tuple(attributes),
|
)
|
||||||
()
|
+ tuple(attributes),
|
||||||
|
(),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
log_message = '(fil) %s -> %s [Reject:%s]' % (
|
log_message = "(fil) %s -> %s [Reject:%s]" % (
|
||||||
sw_name + u":" + port + u"/" + str(room),
|
sw_name + u":" + port + u"/" + str(room),
|
||||||
mac,
|
mac,
|
||||||
(reason and u': ' + reason).encode('utf-8')
|
(reason and u": " + reason).encode("utf-8"),
|
||||||
)
|
)
|
||||||
logger.info(log_message)
|
logger.info(log_message)
|
||||||
|
|
||||||
return (
|
return (radiusd.RLM_MODULE_REJECT, tuple(attributes), ())
|
||||||
radiusd.RLM_MODULE_REJECT,
|
|
||||||
tuple(attributes),
|
|
||||||
()
|
|
||||||
)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return radiusd.RLM_MODULE_OK
|
return radiusd.RLM_MODULE_OK
|
||||||
|
@ -282,13 +263,14 @@ def detach(_=None):
|
||||||
|
|
||||||
def find_nas_from_request(nas_id):
|
def find_nas_from_request(nas_id):
|
||||||
""" Get the nas object from its ID """
|
""" Get the nas object from its ID """
|
||||||
nas = (Interface.objects
|
nas = (
|
||||||
.filter(
|
Interface.objects.filter(
|
||||||
Q(domain=Domain.objects.filter(name=nas_id)) |
|
Q(domain=Domain.objects.filter(name=nas_id))
|
||||||
Q(ipv4=IpList.objects.filter(ipv4=nas_id))
|
| Q(ipv4=IpList.objects.filter(ipv4=nas_id))
|
||||||
|
)
|
||||||
|
.select_related("machine_type")
|
||||||
|
.select_related("machine__switch__stack")
|
||||||
)
|
)
|
||||||
.select_related('machine_type')
|
|
||||||
.select_related('machine__switch__stack'))
|
|
||||||
return nas.first()
|
return nas.first()
|
||||||
|
|
||||||
|
|
||||||
|
@ -300,17 +282,18 @@ def check_user_machine_and_register(nas_type, username, mac_address):
|
||||||
interface = Interface.objects.filter(mac_address=mac_address).first()
|
interface = Interface.objects.filter(mac_address=mac_address).first()
|
||||||
user = User.objects.filter(pseudo__iexact=username).first()
|
user = User.objects.filter(pseudo__iexact=username).first()
|
||||||
if not user:
|
if not user:
|
||||||
return (False, u"User inconnu", '')
|
return (False, u"User inconnu", "")
|
||||||
if not user.has_access():
|
if not user.has_access():
|
||||||
return (False, u"Adherent non cotisant", '')
|
return (False, u"Adherent non cotisant", "")
|
||||||
if interface:
|
if interface:
|
||||||
if interface.machine.user != user:
|
if interface.machine.user != user:
|
||||||
return (False,
|
return (
|
||||||
u"Machine enregistree sur le compte d'un autre "
|
False,
|
||||||
"user...",
|
u"Machine enregistree sur le compte d'un autre " "user...",
|
||||||
'')
|
"",
|
||||||
|
)
|
||||||
elif not interface.is_active:
|
elif not interface.is_active:
|
||||||
return (False, u"Machine desactivee", '')
|
return (False, u"Machine desactivee", "")
|
||||||
elif not interface.ipv4:
|
elif not interface.ipv4:
|
||||||
interface.assign_ipv4()
|
interface.assign_ipv4()
|
||||||
return (True, u"Ok, Reassignation de l'ipv4", user.pwd_ntlm)
|
return (True, u"Ok, Reassignation de l'ipv4", user.pwd_ntlm)
|
||||||
|
@ -320,19 +303,16 @@ def check_user_machine_and_register(nas_type, username, mac_address):
|
||||||
if nas_type.autocapture_mac:
|
if nas_type.autocapture_mac:
|
||||||
result, reason = user.autoregister_machine(mac_address, nas_type)
|
result, reason = user.autoregister_machine(mac_address, nas_type)
|
||||||
if result:
|
if result:
|
||||||
return (True,
|
return (True, u"Access Ok, Capture de la mac...", user.pwd_ntlm)
|
||||||
u'Access Ok, Capture de la mac...',
|
|
||||||
user.pwd_ntlm)
|
|
||||||
else:
|
else:
|
||||||
return (False, u'Erreur dans le register mac %s' % reason, '')
|
return (False, u"Erreur dans le register mac %s" % reason, "")
|
||||||
else:
|
else:
|
||||||
return (False, u'Machine inconnue', '')
|
return (False, u"Machine inconnue", "")
|
||||||
else:
|
else:
|
||||||
return (False, u"Machine inconnue", '')
|
return (False, u"Machine inconnue", "")
|
||||||
|
|
||||||
|
|
||||||
def decide_vlan_switch(nas_machine, nas_type, port_number,
|
def decide_vlan_switch(nas_machine, nas_type, port_number, mac_address):
|
||||||
mac_address):
|
|
||||||
"""Fonction de placement vlan pour un switch en radius filaire auth par
|
"""Fonction de placement vlan pour un switch en radius filaire auth par
|
||||||
mac.
|
mac.
|
||||||
Plusieurs modes :
|
Plusieurs modes :
|
||||||
|
@ -373,32 +353,27 @@ def decide_vlan_switch(nas_machine, nas_type, port_number,
|
||||||
- Attributs supplémentaires (attribut:str, operateur:str, valeur:str)
|
- Attributs supplémentaires (attribut:str, operateur:str, valeur:str)
|
||||||
"""
|
"""
|
||||||
attributes_kwargs = {
|
attributes_kwargs = {
|
||||||
'client_mac' : str(mac_address),
|
"client_mac": str(mac_address),
|
||||||
'switch_port' : str(port_number),
|
"switch_port": str(port_number),
|
||||||
}
|
}
|
||||||
# Get port from switch and port number
|
# Get port from switch and port number
|
||||||
extra_log = ""
|
extra_log = ""
|
||||||
# Si le NAS est inconnu, on place sur le vlan defaut
|
# Si le NAS est inconnu, on place sur le vlan defaut
|
||||||
if not nas_machine:
|
if not nas_machine:
|
||||||
return (
|
return (
|
||||||
'?',
|
"?",
|
||||||
u'Chambre inconnue',
|
u"Chambre inconnue",
|
||||||
u'Nas inconnu',
|
u"Nas inconnu",
|
||||||
RadiusOption.get_cached_value('vlan_decision_ok').vlan_id,
|
RadiusOption.get_cached_value("vlan_decision_ok").vlan_id,
|
||||||
True,
|
True,
|
||||||
RadiusOption.get_attributes('ok_attributes', attributes_kwargs)
|
RadiusOption.get_attributes("ok_attributes", attributes_kwargs),
|
||||||
)
|
)
|
||||||
|
|
||||||
sw_name = str(getattr(nas_machine, 'short_name', str(nas_machine)))
|
sw_name = str(getattr(nas_machine, "short_name", str(nas_machine)))
|
||||||
|
|
||||||
switch = Switch.objects.filter(machine_ptr=nas_machine).first()
|
switch = Switch.objects.filter(machine_ptr=nas_machine).first()
|
||||||
attributes_kwargs['switch_ip'] = str(switch.ipv4)
|
attributes_kwargs["switch_ip"] = str(switch.ipv4)
|
||||||
port = (Port.objects
|
port = Port.objects.filter(switch=switch, port=port_number).first()
|
||||||
.filter(
|
|
||||||
switch=switch,
|
|
||||||
port=port_number
|
|
||||||
)
|
|
||||||
.first())
|
|
||||||
|
|
||||||
# Si le port est inconnu, on place sur le vlan defaut
|
# Si le port est inconnu, on place sur le vlan defaut
|
||||||
# Aucune information particulière ne permet de déterminer quelle
|
# Aucune information particulière ne permet de déterminer quelle
|
||||||
|
@ -407,10 +382,12 @@ def decide_vlan_switch(nas_machine, nas_type, port_number,
|
||||||
return (
|
return (
|
||||||
sw_name,
|
sw_name,
|
||||||
"Port inconnu",
|
"Port inconnu",
|
||||||
u'Port inconnu',
|
u"Port inconnu",
|
||||||
getattr(RadiusOption.get_cached_value('unknown_port_vlan'), 'vlan_id', None),
|
getattr(
|
||||||
RadiusOption.get_cached_value('unknown_port')!= RadiusOption.REJECT,
|
RadiusOption.get_cached_value("unknown_port_vlan"), "vlan_id", None
|
||||||
RadiusOption.get_attributes('unknown_port_attributes', attributes_kwargs)
|
),
|
||||||
|
RadiusOption.get_cached_value("unknown_port") != RadiusOption.REJECT,
|
||||||
|
RadiusOption.get_attributes("unknown_port_attributes", attributes_kwargs),
|
||||||
)
|
)
|
||||||
|
|
||||||
# On récupère le profil du port
|
# On récupère le profil du port
|
||||||
|
@ -423,35 +400,36 @@ def decide_vlan_switch(nas_machine, nas_type, port_number,
|
||||||
extra_log = u"Force sur vlan " + str(DECISION_VLAN)
|
extra_log = u"Force sur vlan " + str(DECISION_VLAN)
|
||||||
attributes = ()
|
attributes = ()
|
||||||
else:
|
else:
|
||||||
DECISION_VLAN = RadiusOption.get_cached_value('vlan_decision_ok').vlan_id
|
DECISION_VLAN = RadiusOption.get_cached_value("vlan_decision_ok").vlan_id
|
||||||
attributes = RadiusOption.get_attributes('ok_attributes', attributes_kwargs)
|
attributes = RadiusOption.get_attributes("ok_attributes", attributes_kwargs)
|
||||||
|
|
||||||
# Si le port est désactivé, on rejette la connexion
|
# Si le port est désactivé, on rejette la connexion
|
||||||
if not port.state:
|
if not port.state:
|
||||||
return (sw_name, port.room, u'Port desactive', None, False, ())
|
return (sw_name, port.room, u"Port desactive", None, False, ())
|
||||||
|
|
||||||
# Si radius est désactivé, on laisse passer
|
# Si radius est désactivé, on laisse passer
|
||||||
if port_profile.radius_type == 'NO':
|
if port_profile.radius_type == "NO":
|
||||||
return (sw_name,
|
return (
|
||||||
|
sw_name,
|
||||||
"",
|
"",
|
||||||
u"Pas d'authentification sur ce port" + extra_log,
|
u"Pas d'authentification sur ce port" + extra_log,
|
||||||
DECISION_VLAN,
|
DECISION_VLAN,
|
||||||
True,
|
True,
|
||||||
attributes
|
attributes,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Si le 802.1X est activé sur ce port, cela veut dire que la personne a
|
# Si le 802.1X est activé sur ce port, cela veut dire que la personne a
|
||||||
# été accept précédemment
|
# été accept précédemment
|
||||||
# Par conséquent, on laisse passer sur le bon vlan
|
# Par conséquent, on laisse passer sur le bon vlan
|
||||||
if (nas_type.port_access_mode, port_profile.radius_type) == ('802.1X', '802.1X'):
|
if (nas_type.port_access_mode, port_profile.radius_type) == ("802.1X", "802.1X"):
|
||||||
room = port.room or "Chambre/local inconnu"
|
room = port.room or "Chambre/local inconnu"
|
||||||
return (
|
return (
|
||||||
sw_name,
|
sw_name,
|
||||||
room,
|
room,
|
||||||
u'Acceptation authentification 802.1X',
|
u"Acceptation authentification 802.1X",
|
||||||
DECISION_VLAN,
|
DECISION_VLAN,
|
||||||
True,
|
True,
|
||||||
attributes
|
attributes,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Sinon, cela veut dire qu'on fait de l'auth radius par mac
|
# Sinon, cela veut dire qu'on fait de l'auth radius par mac
|
||||||
|
@ -460,16 +438,20 @@ def decide_vlan_switch(nas_machine, nas_type, port_number,
|
||||||
# (anti squattage)
|
# (anti squattage)
|
||||||
# Il n'est pas possible de se connecter sur une prise strict sans adhérent
|
# Il n'est pas possible de se connecter sur une prise strict sans adhérent
|
||||||
# à jour de cotis dedans
|
# à jour de cotis dedans
|
||||||
if port_profile.radius_mode == 'STRICT':
|
if port_profile.radius_mode == "STRICT":
|
||||||
room = port.room
|
room = port.room
|
||||||
if not room:
|
if not room:
|
||||||
return (
|
return (
|
||||||
sw_name,
|
sw_name,
|
||||||
"Inconnue",
|
"Inconnue",
|
||||||
u'Chambre inconnue',
|
u"Chambre inconnue",
|
||||||
getattr(RadiusOption.get_cached_value('unknown_room_vlan'), 'vlan_id', None),
|
getattr(
|
||||||
RadiusOption.get_cached_value('unknown_room')!= RadiusOption.REJECT,
|
RadiusOption.get_cached_value("unknown_room_vlan"), "vlan_id", None
|
||||||
RadiusOption.get_attributes('unknown_room_attributes', attributes_kwargs),
|
),
|
||||||
|
RadiusOption.get_cached_value("unknown_room") != RadiusOption.REJECT,
|
||||||
|
RadiusOption.get_attributes(
|
||||||
|
"unknown_room_attributes", attributes_kwargs
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
room_user = User.objects.filter(
|
room_user = User.objects.filter(
|
||||||
|
@ -479,41 +461,52 @@ def decide_vlan_switch(nas_machine, nas_type, port_number,
|
||||||
return (
|
return (
|
||||||
sw_name,
|
sw_name,
|
||||||
room,
|
room,
|
||||||
u'Chambre non cotisante',
|
u"Chambre non cotisante",
|
||||||
getattr(RadiusOption.get_cached_value('non_member_vlan'), 'vlan_id', None),
|
getattr(
|
||||||
RadiusOption.get_cached_value('non_member')!= RadiusOption.REJECT,
|
RadiusOption.get_cached_value("non_member_vlan"), "vlan_id", None
|
||||||
RadiusOption.get_attributes('non_member_attributes', attributes_kwargs),
|
),
|
||||||
|
RadiusOption.get_cached_value("non_member") != RadiusOption.REJECT,
|
||||||
|
RadiusOption.get_attributes("non_member_attributes", attributes_kwargs),
|
||||||
)
|
)
|
||||||
for user in room_user:
|
for user in room_user:
|
||||||
if user.is_ban() or user.state != User.STATE_ACTIVE:
|
if user.is_ban() or user.state != User.STATE_ACTIVE:
|
||||||
return (
|
return (
|
||||||
sw_name,
|
sw_name,
|
||||||
room,
|
room,
|
||||||
u'Utilisateur banni ou desactive',
|
u"Utilisateur banni ou desactive",
|
||||||
getattr(RadiusOption.get_cached_value('banned_vlan'), 'vlan_id', None),
|
getattr(
|
||||||
RadiusOption.get_cached_value('banned')!= RadiusOption.REJECT,
|
RadiusOption.get_cached_value("banned_vlan"), "vlan_id", None
|
||||||
RadiusOption.get_attributes('banned_attributes', attributes_kwargs),
|
),
|
||||||
|
RadiusOption.get_cached_value("banned") != RadiusOption.REJECT,
|
||||||
|
RadiusOption.get_attributes("banned_attributes", attributes_kwargs),
|
||||||
)
|
)
|
||||||
elif not (user.is_connected() or user.is_whitelisted()):
|
elif not (user.is_connected() or user.is_whitelisted()):
|
||||||
return (
|
return (
|
||||||
sw_name,
|
sw_name,
|
||||||
room,
|
room,
|
||||||
u'Utilisateur non cotisant',
|
u"Utilisateur non cotisant",
|
||||||
getattr(RadiusOption.get_cached_value('non_member_vlan'), 'vlan_id', None),
|
getattr(
|
||||||
RadiusOption.get_cached_value('non_member')!= RadiusOption.REJECT,
|
RadiusOption.get_cached_value("non_member_vlan"),
|
||||||
RadiusOption.get_attributes('non_member_attributes', attributes_kwargs),
|
"vlan_id",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
RadiusOption.get_cached_value("non_member") != RadiusOption.REJECT,
|
||||||
|
RadiusOption.get_attributes(
|
||||||
|
"non_member_attributes", attributes_kwargs
|
||||||
|
),
|
||||||
)
|
)
|
||||||
# else: user OK, on passe à la verif MAC
|
# else: user OK, on passe à la verif MAC
|
||||||
|
|
||||||
# Si on fait de l'auth par mac, on cherche l'interface
|
# Si on fait de l'auth par mac, on cherche l'interface
|
||||||
# via sa mac dans la bdd
|
# via sa mac dans la bdd
|
||||||
if port_profile.radius_mode == 'COMMON' or port_profile.radius_mode == 'STRICT':
|
if port_profile.radius_mode == "COMMON" or port_profile.radius_mode == "STRICT":
|
||||||
# Authentification par mac
|
# Authentification par mac
|
||||||
interface = (Interface.objects
|
interface = (
|
||||||
.filter(mac_address=mac_address)
|
Interface.objects.filter(mac_address=mac_address)
|
||||||
.select_related('machine__user')
|
.select_related("machine__user")
|
||||||
.select_related('ipv4')
|
.select_related("ipv4")
|
||||||
.first())
|
.first()
|
||||||
|
)
|
||||||
if not interface:
|
if not interface:
|
||||||
room = port.room
|
room = port.room
|
||||||
# On essaye de register la mac, si l'autocapture a été activée,
|
# On essaye de register la mac, si l'autocapture a été activée,
|
||||||
|
@ -522,10 +515,17 @@ def decide_vlan_switch(nas_machine, nas_type, port_number,
|
||||||
return (
|
return (
|
||||||
sw_name,
|
sw_name,
|
||||||
room,
|
room,
|
||||||
u'Machine Inconnue',
|
u"Machine Inconnue",
|
||||||
getattr(RadiusOption.get_cached_value('unknown_machine_vlan'), 'vlan_id', None),
|
getattr(
|
||||||
RadiusOption.get_cached_value('unknown_machine')!= RadiusOption.REJECT,
|
RadiusOption.get_cached_value("unknown_machine_vlan"),
|
||||||
RadiusOption.get_attributes('unknown_machine_attributes', attributes_kwargs),
|
"vlan_id",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
RadiusOption.get_cached_value("unknown_machine")
|
||||||
|
!= RadiusOption.REJECT,
|
||||||
|
RadiusOption.get_attributes(
|
||||||
|
"unknown_machine_attributes", attributes_kwargs
|
||||||
|
),
|
||||||
)
|
)
|
||||||
# Sinon on bascule sur la politique définie dans les options
|
# Sinon on bascule sur la politique définie dans les options
|
||||||
# radius.
|
# radius.
|
||||||
|
@ -533,10 +533,17 @@ def decide_vlan_switch(nas_machine, nas_type, port_number,
|
||||||
return (
|
return (
|
||||||
sw_name,
|
sw_name,
|
||||||
"",
|
"",
|
||||||
u'Machine inconnue',
|
u"Machine inconnue",
|
||||||
getattr(RadiusOption.get_cached_value('unknown_machine_vlan'), 'vlan_id', None),
|
getattr(
|
||||||
RadiusOption.get_cached_value('unknown_machine')!= RadiusOption.REJECT,
|
RadiusOption.get_cached_value("unknown_machine_vlan"),
|
||||||
RadiusOption.get_attributes('unknown_machine_attributes', attributes_kwargs),
|
"vlan_id",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
RadiusOption.get_cached_value("unknown_machine")
|
||||||
|
!= RadiusOption.REJECT,
|
||||||
|
RadiusOption.get_attributes(
|
||||||
|
"unknown_machine_attributes", attributes_kwargs
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
# L'interface a été trouvée, on vérifie qu'elle est active,
|
# L'interface a été trouvée, on vérifie qu'elle est active,
|
||||||
|
@ -549,23 +556,31 @@ def decide_vlan_switch(nas_machine, nas_type, port_number,
|
||||||
return (
|
return (
|
||||||
sw_name,
|
sw_name,
|
||||||
room,
|
room,
|
||||||
u'Adherent banni',
|
u"Adherent banni",
|
||||||
getattr(RadiusOption.get_cached_value('banned_vlan'), 'vlan_id', None),
|
getattr(
|
||||||
RadiusOption.get_cached_value('banned')!= RadiusOption.REJECT,
|
RadiusOption.get_cached_value("banned_vlan"), "vlan_id", None
|
||||||
RadiusOption.get_attributes('banned_attributes', attributes_kwargs),
|
),
|
||||||
|
RadiusOption.get_cached_value("banned") != RadiusOption.REJECT,
|
||||||
|
RadiusOption.get_attributes("banned_attributes", attributes_kwargs),
|
||||||
)
|
)
|
||||||
if not interface.is_active:
|
if not interface.is_active:
|
||||||
return (
|
return (
|
||||||
sw_name,
|
sw_name,
|
||||||
room,
|
room,
|
||||||
u'Machine non active / adherent non cotisant',
|
u"Machine non active / adherent non cotisant",
|
||||||
getattr(RadiusOption.get_cached_value('non_member_vlan'), 'vlan_id', None),
|
getattr(
|
||||||
RadiusOption.get_cached_value('non_member')!= RadiusOption.REJECT,
|
RadiusOption.get_cached_value("non_member_vlan"),
|
||||||
RadiusOption.get_attributes('non_member_attributes', attributes_kwargs),
|
"vlan_id",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
RadiusOption.get_cached_value("non_member") != RadiusOption.REJECT,
|
||||||
|
RadiusOption.get_attributes(
|
||||||
|
"non_member_attributes", attributes_kwargs
|
||||||
|
),
|
||||||
)
|
)
|
||||||
# Si on choisi de placer les machines sur le vlan
|
# Si on choisi de placer les machines sur le vlan
|
||||||
# correspondant à leur type :
|
# correspondant à leur type :
|
||||||
if RadiusOption.get_cached_value('radius_general_policy') == 'MACHINE':
|
if RadiusOption.get_cached_value("radius_general_policy") == "MACHINE":
|
||||||
DECISION_VLAN = interface.machine_type.ip_type.vlan.vlan_id
|
DECISION_VLAN = interface.machine_type.ip_type.vlan.vlan_id
|
||||||
if not interface.ipv4:
|
if not interface.ipv4:
|
||||||
interface.assign_ipv4()
|
interface.assign_ipv4()
|
||||||
|
@ -575,14 +590,14 @@ def decide_vlan_switch(nas_machine, nas_type, port_number,
|
||||||
u"Ok, Reassignation de l'ipv4" + extra_log,
|
u"Ok, Reassignation de l'ipv4" + extra_log,
|
||||||
DECISION_VLAN,
|
DECISION_VLAN,
|
||||||
True,
|
True,
|
||||||
attributes
|
attributes,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return (
|
return (
|
||||||
sw_name,
|
sw_name,
|
||||||
room,
|
room,
|
||||||
u'Machine OK' + extra_log,
|
u"Machine OK" + extra_log,
|
||||||
DECISION_VLAN,
|
DECISION_VLAN,
|
||||||
True,
|
True,
|
||||||
attributes
|
attributes,
|
||||||
)
|
)
|
||||||
|
|
|
@ -38,11 +38,9 @@ def can_view(user):
|
||||||
A couple (allowed, msg) where allowed is a boolean which is True if
|
A couple (allowed, msg) where allowed is a boolean which is True if
|
||||||
viewing is granted and msg is a message (can be None).
|
viewing is granted and msg is a message (can be None).
|
||||||
"""
|
"""
|
||||||
can = user.has_module_perms('admin')
|
can = user.has_module_perms("admin")
|
||||||
return (
|
return (
|
||||||
can,
|
can,
|
||||||
None if can else _("You don't have the right to view this"
|
None if can else _("You don't have the right to view this" " application."),
|
||||||
" application."),
|
"admin",
|
||||||
'admin'
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -34,12 +34,14 @@ def classname(obj):
|
||||||
""" Returns the object class name """
|
""" Returns the object class name """
|
||||||
return obj.__class__.__name__
|
return obj.__class__.__name__
|
||||||
|
|
||||||
|
|
||||||
@register.filter
|
@register.filter
|
||||||
def is_facture(baseinvoice):
|
def is_facture(baseinvoice):
|
||||||
"""Returns True if a baseinvoice has a `Facture` child."""
|
"""Returns True if a baseinvoice has a `Facture` child."""
|
||||||
return hasattr(baseinvoice, 'facture')
|
return hasattr(baseinvoice, "facture")
|
||||||
|
|
||||||
@register.inclusion_tag('buttons/history.html')
|
|
||||||
|
@register.inclusion_tag("buttons/history.html")
|
||||||
def history_button(instance, text=False, html_class=True):
|
def history_button(instance, text=False, html_class=True):
|
||||||
"""Creates the correct history button for an instance.
|
"""Creates the correct history button for an instance.
|
||||||
|
|
||||||
|
@ -51,9 +53,9 @@ def history_button(instance, text=False, html_class=True):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return {
|
return {
|
||||||
'application': instance._meta.app_label,
|
"application": instance._meta.app_label,
|
||||||
'name': instance._meta.model_name,
|
"name": instance._meta.model_name,
|
||||||
'id': instance.id,
|
"id": instance.id,
|
||||||
'text': text,
|
"text": text,
|
||||||
'class': html_class,
|
"class": html_class,
|
||||||
}
|
}
|
||||||
|
|
24
logs/urls.py
24
logs/urls.py
|
@ -30,18 +30,20 @@ from django.conf.urls import url
|
||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^$', views.index, name='index'),
|
url(r"^$", views.index, name="index"),
|
||||||
url(r'^stats_logs$', views.stats_logs, name='stats-logs'),
|
url(r"^stats_logs$", views.stats_logs, name="stats-logs"),
|
||||||
url(r'^revert_action/(?P<revision_id>[0-9]+)$',
|
|
||||||
views.revert_action,
|
|
||||||
name='revert-action'),
|
|
||||||
url(r'^stats_general/$', views.stats_general, name='stats-general'),
|
|
||||||
url(r'^stats_models/$', views.stats_models, name='stats-models'),
|
|
||||||
url(r'^stats_users/$', views.stats_users, name='stats-users'),
|
|
||||||
url(r'^stats_actions/$', views.stats_actions, name='stats-actions'),
|
|
||||||
url(
|
url(
|
||||||
r'(?P<application>\w+)/(?P<object_name>\w+)/(?P<object_id>[0-9]+)$',
|
r"^revert_action/(?P<revision_id>[0-9]+)$",
|
||||||
|
views.revert_action,
|
||||||
|
name="revert-action",
|
||||||
|
),
|
||||||
|
url(r"^stats_general/$", views.stats_general, name="stats-general"),
|
||||||
|
url(r"^stats_models/$", views.stats_models, name="stats-models"),
|
||||||
|
url(r"^stats_users/$", views.stats_users, name="stats-users"),
|
||||||
|
url(r"^stats_actions/$", views.stats_actions, name="stats-actions"),
|
||||||
|
url(
|
||||||
|
r"(?P<application>\w+)/(?P<object_name>\w+)/(?P<object_id>[0-9]+)$",
|
||||||
views.history,
|
views.history,
|
||||||
name='history',
|
name="history",
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
443
logs/views.py
443
logs/views.py
|
@ -60,16 +60,9 @@ from users.models import (
|
||||||
Ban,
|
Ban,
|
||||||
Whitelist,
|
Whitelist,
|
||||||
Adherent,
|
Adherent,
|
||||||
Club
|
Club,
|
||||||
)
|
|
||||||
from cotisations.models import (
|
|
||||||
Facture,
|
|
||||||
Vente,
|
|
||||||
Article,
|
|
||||||
Banque,
|
|
||||||
Paiement,
|
|
||||||
Cotisation
|
|
||||||
)
|
)
|
||||||
|
from cotisations.models import Facture, Vente, Article, Banque, Paiement, Cotisation
|
||||||
from machines.models import (
|
from machines.models import (
|
||||||
Machine,
|
Machine,
|
||||||
MachineType,
|
MachineType,
|
||||||
|
@ -84,7 +77,7 @@ from machines.models import (
|
||||||
Nas,
|
Nas,
|
||||||
SOA,
|
SOA,
|
||||||
Mx,
|
Mx,
|
||||||
Ns
|
Ns,
|
||||||
)
|
)
|
||||||
from topologie.models import (
|
from topologie.models import (
|
||||||
Switch,
|
Switch,
|
||||||
|
@ -93,7 +86,7 @@ from topologie.models import (
|
||||||
Stack,
|
Stack,
|
||||||
ModelSwitch,
|
ModelSwitch,
|
||||||
ConstructorSwitch,
|
ConstructorSwitch,
|
||||||
AccessPoint
|
AccessPoint,
|
||||||
)
|
)
|
||||||
from preferences.models import GeneralOption
|
from preferences.models import GeneralOption
|
||||||
from re2o.views import form
|
from re2o.views import form
|
||||||
|
@ -105,36 +98,24 @@ from re2o.utils import (
|
||||||
all_active_assigned_interfaces_count,
|
all_active_assigned_interfaces_count,
|
||||||
all_active_interfaces_count,
|
all_active_interfaces_count,
|
||||||
)
|
)
|
||||||
from re2o.base import (
|
from re2o.base import re2o_paginator, SortTable
|
||||||
re2o_paginator,
|
from re2o.acl import can_view_all, can_view_app, can_edit_history
|
||||||
SortTable
|
|
||||||
)
|
|
||||||
from re2o.acl import (
|
|
||||||
can_view_all,
|
|
||||||
can_view_app,
|
|
||||||
can_edit_history,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@can_view_app('logs')
|
@can_view_app("logs")
|
||||||
def index(request):
|
def index(request):
|
||||||
"""Affiche les logs affinés, date reformatées, selectionne
|
"""Affiche les logs affinés, date reformatées, selectionne
|
||||||
les event importants (ajout de droits, ajout de ban/whitelist)"""
|
les event importants (ajout de droits, ajout de ban/whitelist)"""
|
||||||
pagination_number = GeneralOption.get_cached_value('pagination_number')
|
pagination_number = GeneralOption.get_cached_value("pagination_number")
|
||||||
# The types of content kept for display
|
# The types of content kept for display
|
||||||
content_type_filter = ['ban', 'whitelist', 'vente', 'interface', 'user']
|
content_type_filter = ["ban", "whitelist", "vente", "interface", "user"]
|
||||||
# Select only wanted versions
|
# Select only wanted versions
|
||||||
versions = Version.objects.filter(
|
versions = Version.objects.filter(
|
||||||
content_type__in=ContentType.objects.filter(
|
content_type__in=ContentType.objects.filter(model__in=content_type_filter)
|
||||||
model__in=content_type_filter
|
).select_related("revision")
|
||||||
)
|
|
||||||
).select_related('revision')
|
|
||||||
versions = SortTable.sort(
|
versions = SortTable.sort(
|
||||||
versions,
|
versions, request.GET.get("col"), request.GET.get("order"), SortTable.LOGS_INDEX
|
||||||
request.GET.get('col'),
|
|
||||||
request.GET.get('order'),
|
|
||||||
SortTable.LOGS_INDEX
|
|
||||||
)
|
)
|
||||||
versions = re2o_paginator(request, versions, pagination_number)
|
versions = re2o_paginator(request, versions, pagination_number)
|
||||||
# Force to have a list instead of QuerySet
|
# Force to have a list instead of QuerySet
|
||||||
|
@ -146,20 +127,21 @@ def index(request):
|
||||||
if versions.object_list[i].object:
|
if versions.object_list[i].object:
|
||||||
version = versions.object_list[i]
|
version = versions.object_list[i]
|
||||||
versions.object_list[i] = {
|
versions.object_list[i] = {
|
||||||
'rev_id': version.revision.id,
|
"rev_id": version.revision.id,
|
||||||
'comment': version.revision.comment,
|
"comment": version.revision.comment,
|
||||||
'datetime': version.revision.date_created,
|
"datetime": version.revision.date_created,
|
||||||
'username':
|
"username": version.revision.user.get_username()
|
||||||
version.revision.user.get_username()
|
if version.revision.user
|
||||||
if version.revision.user else '?',
|
else "?",
|
||||||
'user_id': version.revision.user_id,
|
"user_id": version.revision.user_id,
|
||||||
'version': version}
|
"version": version,
|
||||||
|
}
|
||||||
else:
|
else:
|
||||||
to_remove.insert(0, i)
|
to_remove.insert(0, i)
|
||||||
# Remove all tagged invalid items
|
# Remove all tagged invalid items
|
||||||
for i in to_remove:
|
for i in to_remove:
|
||||||
versions.object_list.pop(i)
|
versions.object_list.pop(i)
|
||||||
return render(request, 'logs/index.html', {'versions_list': versions})
|
return render(request, "logs/index.html", {"versions_list": versions})
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
@ -167,19 +149,20 @@ def index(request):
|
||||||
def stats_logs(request):
|
def stats_logs(request):
|
||||||
"""Affiche l'ensemble des logs et des modifications sur les objets,
|
"""Affiche l'ensemble des logs et des modifications sur les objets,
|
||||||
classés par date croissante, en vrac"""
|
classés par date croissante, en vrac"""
|
||||||
pagination_number = GeneralOption.get_cached_value('pagination_number')
|
pagination_number = GeneralOption.get_cached_value("pagination_number")
|
||||||
revisions = Revision.objects.all().select_related('user')\
|
revisions = (
|
||||||
.prefetch_related('version_set__object')
|
Revision.objects.all()
|
||||||
|
.select_related("user")
|
||||||
|
.prefetch_related("version_set__object")
|
||||||
|
)
|
||||||
revisions = SortTable.sort(
|
revisions = SortTable.sort(
|
||||||
revisions,
|
revisions,
|
||||||
request.GET.get('col'),
|
request.GET.get("col"),
|
||||||
request.GET.get('order'),
|
request.GET.get("order"),
|
||||||
SortTable.LOGS_STATS_LOGS
|
SortTable.LOGS_STATS_LOGS,
|
||||||
)
|
)
|
||||||
revisions = re2o_paginator(request, revisions, pagination_number)
|
revisions = re2o_paginator(request, revisions, pagination_number)
|
||||||
return render(request, 'logs/stats_logs.html', {
|
return render(request, "logs/stats_logs.html", {"revisions_list": revisions})
|
||||||
'revisions_list': revisions
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
@ -193,11 +176,12 @@ def revert_action(request, revision_id):
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
revision.revert()
|
revision.revert()
|
||||||
messages.success(request, _("The action was deleted."))
|
messages.success(request, _("The action was deleted."))
|
||||||
return redirect(reverse('logs:index'))
|
return redirect(reverse("logs:index"))
|
||||||
return form({
|
return form(
|
||||||
'objet': revision,
|
{"objet": revision, "objet_name": revision.__class__.__name__},
|
||||||
'objet_name': revision.__class__.__name__
|
"logs/delete.html",
|
||||||
}, 'logs/delete.html', request)
|
request,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
@ -207,115 +191,128 @@ def stats_general(request):
|
||||||
range, et les statistiques générales sur les users : users actifs,
|
range, et les statistiques générales sur les users : users actifs,
|
||||||
cotisants, activés, archivés, etc"""
|
cotisants, activés, archivés, etc"""
|
||||||
ip_dict = dict()
|
ip_dict = dict()
|
||||||
for ip_range in IpType.objects.select_related('vlan').all():
|
for ip_range in IpType.objects.select_related("vlan").all():
|
||||||
all_ip = IpList.objects.filter(ip_type=ip_range)
|
all_ip = IpList.objects.filter(ip_type=ip_range)
|
||||||
used_ip = Interface.objects.filter(ipv4__in=all_ip).count()
|
used_ip = Interface.objects.filter(ipv4__in=all_ip).count()
|
||||||
active_ip = all_active_assigned_interfaces_count().filter(
|
active_ip = (
|
||||||
ipv4__in=IpList.objects.filter(ip_type=ip_range)
|
all_active_assigned_interfaces_count()
|
||||||
).count()
|
.filter(ipv4__in=IpList.objects.filter(ip_type=ip_range))
|
||||||
ip_dict[ip_range] = [ip_range, ip_range.vlan, all_ip.count(),
|
.count()
|
||||||
used_ip, active_ip, all_ip.count()-used_ip]
|
)
|
||||||
|
ip_dict[ip_range] = [
|
||||||
|
ip_range,
|
||||||
|
ip_range.vlan,
|
||||||
|
all_ip.count(),
|
||||||
|
used_ip,
|
||||||
|
active_ip,
|
||||||
|
all_ip.count() - used_ip,
|
||||||
|
]
|
||||||
_all_adherent = all_adherent(including_asso=False)
|
_all_adherent = all_adherent(including_asso=False)
|
||||||
_all_has_access = all_has_access(including_asso=False)
|
_all_has_access = all_has_access(including_asso=False)
|
||||||
_all_baned = all_baned()
|
_all_baned = all_baned()
|
||||||
_all_whitelisted = all_whitelisted()
|
_all_whitelisted = all_whitelisted()
|
||||||
_all_active_interfaces_count = all_active_interfaces_count()
|
_all_active_interfaces_count = all_active_interfaces_count()
|
||||||
_all_active_assigned_interfaces_count = \
|
_all_active_assigned_interfaces_count = all_active_assigned_interfaces_count()
|
||||||
all_active_assigned_interfaces_count()
|
|
||||||
stats = [
|
stats = [
|
||||||
[ # First set of data (about users)
|
[ # First set of data (about users)
|
||||||
[ # Headers
|
[ # Headers
|
||||||
_("Category"),
|
_("Category"),
|
||||||
_("Number of users (members and clubs)"),
|
_("Number of users (members and clubs)"),
|
||||||
_("Number of members"),
|
_("Number of members"),
|
||||||
_("Number of clubs")
|
_("Number of clubs"),
|
||||||
],
|
],
|
||||||
{ # Data
|
{ # Data
|
||||||
'active_users': [
|
"active_users": [
|
||||||
_("Activated users"),
|
_("Activated users"),
|
||||||
User.objects.filter(state=User.STATE_ACTIVE).count(),
|
User.objects.filter(state=User.STATE_ACTIVE).count(),
|
||||||
(Adherent.objects
|
(Adherent.objects.filter(state=Adherent.STATE_ACTIVE).count()),
|
||||||
.filter(state=Adherent.STATE_ACTIVE)
|
Club.objects.filter(state=Club.STATE_ACTIVE).count(),
|
||||||
.count()),
|
|
||||||
Club.objects.filter(state=Club.STATE_ACTIVE).count()
|
|
||||||
],
|
],
|
||||||
'inactive_users': [
|
"inactive_users": [
|
||||||
_("Disabled users"),
|
_("Disabled users"),
|
||||||
User.objects.filter(state=User.STATE_DISABLED).count(),
|
User.objects.filter(state=User.STATE_DISABLED).count(),
|
||||||
(Adherent.objects
|
(Adherent.objects.filter(state=Adherent.STATE_DISABLED).count()),
|
||||||
.filter(state=Adherent.STATE_DISABLED)
|
Club.objects.filter(state=Club.STATE_DISABLED).count(),
|
||||||
.count()),
|
|
||||||
Club.objects.filter(state=Club.STATE_DISABLED).count()
|
|
||||||
],
|
],
|
||||||
'archive_users': [
|
"archive_users": [
|
||||||
_("Archived users"),
|
_("Archived users"),
|
||||||
User.objects.filter(state=User.STATE_ARCHIVE).count(),
|
User.objects.filter(state=User.STATE_ARCHIVE).count(),
|
||||||
(Adherent.objects
|
(Adherent.objects.filter(state=Adherent.STATE_ARCHIVE).count()),
|
||||||
.filter(state=Adherent.STATE_ARCHIVE)
|
Club.objects.filter(state=Club.STATE_ARCHIVE).count(),
|
||||||
.count()),
|
|
||||||
Club.objects.filter(state=Club.STATE_ARCHIVE).count()
|
|
||||||
],
|
],
|
||||||
'full_archive_users': [
|
"full_archive_users": [
|
||||||
_("Full Archived users"),
|
_("Full Archived users"),
|
||||||
User.objects.filter(state=User.STATE_FULL_ARCHIVE).count(),
|
User.objects.filter(state=User.STATE_FULL_ARCHIVE).count(),
|
||||||
(Adherent.objects
|
(
|
||||||
.filter(state=Adherent.STATE_FULL_ARCHIVE)
|
Adherent.objects.filter(
|
||||||
.count()),
|
state=Adherent.STATE_FULL_ARCHIVE
|
||||||
Club.objects.filter(state=Club.STATE_FULL_ARCHIVE).count()
|
).count()
|
||||||
|
),
|
||||||
|
Club.objects.filter(state=Club.STATE_FULL_ARCHIVE).count(),
|
||||||
],
|
],
|
||||||
'not_active_users': [
|
"not_active_users": [
|
||||||
_("Not yet active users"),
|
_("Not yet active users"),
|
||||||
User.objects.filter(state=User.STATE_NOT_YET_ACTIVE).count(),
|
User.objects.filter(state=User.STATE_NOT_YET_ACTIVE).count(),
|
||||||
(Adherent.objects
|
(
|
||||||
.filter(state=Adherent.STATE_NOT_YET_ACTIVE)
|
Adherent.objects.filter(
|
||||||
.count()),
|
state=Adherent.STATE_NOT_YET_ACTIVE
|
||||||
Club.objects.filter(state=Club.STATE_NOT_YET_ACTIVE).count()
|
).count()
|
||||||
|
),
|
||||||
|
Club.objects.filter(state=Club.STATE_NOT_YET_ACTIVE).count(),
|
||||||
],
|
],
|
||||||
'adherent_users': [
|
"adherent_users": [
|
||||||
_("Contributing members"),
|
_("Contributing members"),
|
||||||
_all_adherent.count(),
|
_all_adherent.count(),
|
||||||
_all_adherent.exclude(adherent__isnull=True).count(),
|
_all_adherent.exclude(adherent__isnull=True).count(),
|
||||||
_all_adherent.exclude(club__isnull=True).count()
|
_all_adherent.exclude(club__isnull=True).count(),
|
||||||
],
|
],
|
||||||
'connexion_users': [
|
"connexion_users": [
|
||||||
_("Users benefiting from a connection"),
|
_("Users benefiting from a connection"),
|
||||||
_all_has_access.count(),
|
_all_has_access.count(),
|
||||||
_all_has_access.exclude(adherent__isnull=True).count(),
|
_all_has_access.exclude(adherent__isnull=True).count(),
|
||||||
_all_has_access.exclude(club__isnull=True).count()
|
_all_has_access.exclude(club__isnull=True).count(),
|
||||||
],
|
],
|
||||||
'ban_users': [
|
"ban_users": [
|
||||||
_("Banned users"),
|
_("Banned users"),
|
||||||
_all_baned.count(),
|
_all_baned.count(),
|
||||||
_all_baned.exclude(adherent__isnull=True).count(),
|
_all_baned.exclude(adherent__isnull=True).count(),
|
||||||
_all_baned.exclude(club__isnull=True).count()
|
_all_baned.exclude(club__isnull=True).count(),
|
||||||
],
|
],
|
||||||
'whitelisted_user': [
|
"whitelisted_user": [
|
||||||
_("Users benefiting from a free connection"),
|
_("Users benefiting from a free connection"),
|
||||||
_all_whitelisted.count(),
|
_all_whitelisted.count(),
|
||||||
_all_whitelisted.exclude(adherent__isnull=True).count(),
|
_all_whitelisted.exclude(adherent__isnull=True).count(),
|
||||||
_all_whitelisted.exclude(club__isnull=True).count()
|
_all_whitelisted.exclude(club__isnull=True).count(),
|
||||||
],
|
],
|
||||||
'actives_interfaces': [
|
"actives_interfaces": [
|
||||||
_("Active interfaces (with access to the network)"),
|
_("Active interfaces (with access to the network)"),
|
||||||
_all_active_interfaces_count.count(),
|
_all_active_interfaces_count.count(),
|
||||||
(_all_active_interfaces_count
|
(
|
||||||
.exclude(machine__user__adherent__isnull=True)
|
_all_active_interfaces_count.exclude(
|
||||||
.count()),
|
machine__user__adherent__isnull=True
|
||||||
(_all_active_interfaces_count
|
).count()
|
||||||
.exclude(machine__user__club__isnull=True)
|
),
|
||||||
.count())
|
(
|
||||||
|
_all_active_interfaces_count.exclude(
|
||||||
|
machine__user__club__isnull=True
|
||||||
|
).count()
|
||||||
|
),
|
||||||
],
|
],
|
||||||
'actives_assigned_interfaces': [
|
"actives_assigned_interfaces": [
|
||||||
_("Active interfaces assigned IPv4"),
|
_("Active interfaces assigned IPv4"),
|
||||||
_all_active_assigned_interfaces_count.count(),
|
_all_active_assigned_interfaces_count.count(),
|
||||||
(_all_active_assigned_interfaces_count
|
(
|
||||||
.exclude(machine__user__adherent__isnull=True)
|
_all_active_assigned_interfaces_count.exclude(
|
||||||
.count()),
|
machine__user__adherent__isnull=True
|
||||||
(_all_active_assigned_interfaces_count
|
).count()
|
||||||
.exclude(machine__user__club__isnull=True)
|
),
|
||||||
.count())
|
(
|
||||||
]
|
_all_active_assigned_interfaces_count.exclude(
|
||||||
}
|
machine__user__club__isnull=True
|
||||||
|
).count()
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
[ # Second set of data (about ip adresses)
|
[ # Second set of data (about ip adresses)
|
||||||
[ # Headers
|
[ # Headers
|
||||||
|
@ -324,109 +321,91 @@ def stats_general(request):
|
||||||
_("Total number of IP addresses"),
|
_("Total number of IP addresses"),
|
||||||
_("Number of assigned IP addresses"),
|
_("Number of assigned IP addresses"),
|
||||||
_("Number of IP address assigned to an activated machine"),
|
_("Number of IP address assigned to an activated machine"),
|
||||||
_("Number of nonassigned IP addresses")
|
_("Number of nonassigned IP addresses"),
|
||||||
|
],
|
||||||
|
ip_dict, # Data already prepared
|
||||||
],
|
],
|
||||||
ip_dict # Data already prepared
|
|
||||||
]
|
]
|
||||||
]
|
return render(request, "logs/stats_general.html", {"stats_list": stats})
|
||||||
return render(request, 'logs/stats_general.html', {'stats_list': stats})
|
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@can_view_app('users', 'cotisations', 'machines', 'topologie')
|
@can_view_app("users", "cotisations", "machines", "topologie")
|
||||||
def stats_models(request):
|
def stats_models(request):
|
||||||
"""Statistiques générales, affiche les comptages par models:
|
"""Statistiques générales, affiche les comptages par models:
|
||||||
nombre d'users, d'écoles, de droits, de bannissements,
|
nombre d'users, d'écoles, de droits, de bannissements,
|
||||||
de factures, de ventes, de banque, de machines, etc"""
|
de factures, de ventes, de banque, de machines, etc"""
|
||||||
stats = {
|
stats = {
|
||||||
_("Users"): {
|
_("Users"): {
|
||||||
'users': [User._meta.verbose_name, User.objects.count()],
|
"users": [User._meta.verbose_name, User.objects.count()],
|
||||||
'adherents': [Adherent._meta.verbose_name, Adherent.objects.count()],
|
"adherents": [Adherent._meta.verbose_name, Adherent.objects.count()],
|
||||||
'clubs': [Club._meta.verbose_name, Club.objects.count()],
|
"clubs": [Club._meta.verbose_name, Club.objects.count()],
|
||||||
'serviceuser': [ServiceUser._meta.verbose_name,
|
"serviceuser": [
|
||||||
ServiceUser.objects.count()],
|
ServiceUser._meta.verbose_name,
|
||||||
'school': [School._meta.verbose_name, School.objects.count()],
|
ServiceUser.objects.count(),
|
||||||
'listright': [ListRight._meta.verbose_name, ListRight.objects.count()],
|
],
|
||||||
'listshell': [ListShell._meta.verbose_name, ListShell.objects.count()],
|
"school": [School._meta.verbose_name, School.objects.count()],
|
||||||
'ban': [Ban._meta.verbose_name, Ban.objects.count()],
|
"listright": [ListRight._meta.verbose_name, ListRight.objects.count()],
|
||||||
'whitelist': [Whitelist._meta.verbose_name, Whitelist.objects.count()]
|
"listshell": [ListShell._meta.verbose_name, ListShell.objects.count()],
|
||||||
|
"ban": [Ban._meta.verbose_name, Ban.objects.count()],
|
||||||
|
"whitelist": [Whitelist._meta.verbose_name, Whitelist.objects.count()],
|
||||||
},
|
},
|
||||||
_("Subscriptions"): {
|
_("Subscriptions"): {
|
||||||
'factures': [
|
"factures": [Facture._meta.verbose_name, Facture.objects.count()],
|
||||||
Facture._meta.verbose_name,
|
"vente": [Vente._meta.verbose_name, Vente.objects.count()],
|
||||||
Facture.objects.count()
|
"cotisation": [Cotisation._meta.verbose_name, Cotisation.objects.count()],
|
||||||
],
|
"article": [Article._meta.verbose_name, Article.objects.count()],
|
||||||
'vente': [
|
"banque": [Banque._meta.verbose_name, Banque.objects.count()],
|
||||||
Vente._meta.verbose_name,
|
|
||||||
Vente.objects.count()
|
|
||||||
],
|
|
||||||
'cotisation': [
|
|
||||||
Cotisation._meta.verbose_name,
|
|
||||||
Cotisation.objects.count()
|
|
||||||
],
|
|
||||||
'article': [
|
|
||||||
Article._meta.verbose_name,
|
|
||||||
Article.objects.count()
|
|
||||||
],
|
|
||||||
'banque': [
|
|
||||||
Banque._meta.verbose_name,
|
|
||||||
Banque.objects.count()
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
_("Machines"): {
|
_("Machines"): {
|
||||||
'machine': [Machine._meta.verbose_name,
|
"machine": [Machine._meta.verbose_name, Machine.objects.count()],
|
||||||
Machine.objects.count()],
|
"typemachine": [
|
||||||
'typemachine': [MachineType._meta.verbose_name,
|
MachineType._meta.verbose_name,
|
||||||
MachineType.objects.count()],
|
MachineType.objects.count(),
|
||||||
'typeip': [IpType._meta.verbose_name,
|
|
||||||
IpType.objects.count()],
|
|
||||||
'extension': [Extension._meta.verbose_name,
|
|
||||||
Extension.objects.count()],
|
|
||||||
'interface': [Interface._meta.verbose_name,
|
|
||||||
Interface.objects.count()],
|
|
||||||
'alias': [Domain._meta.verbose_name,
|
|
||||||
Domain.objects.exclude(cname=None).count()],
|
|
||||||
'iplist': [IpList._meta.verbose_name,
|
|
||||||
IpList.objects.count()],
|
|
||||||
'service': [Service._meta.verbose_name,
|
|
||||||
Service.objects.count()],
|
|
||||||
'ouvertureportlist': [
|
|
||||||
OuverturePortList._meta.verbose_name,
|
|
||||||
OuverturePortList.objects.count()
|
|
||||||
],
|
],
|
||||||
'vlan': [Vlan._meta.verbose_name, Vlan.objects.count()],
|
"typeip": [IpType._meta.verbose_name, IpType.objects.count()],
|
||||||
'SOA': [SOA._meta.verbose_name, SOA.objects.count()],
|
"extension": [Extension._meta.verbose_name, Extension.objects.count()],
|
||||||
'Mx': [Mx._meta.verbose_name, Mx.objects.count()],
|
"interface": [Interface._meta.verbose_name, Interface.objects.count()],
|
||||||
'Ns': [Ns._meta.verbose_name, Ns.objects.count()],
|
"alias": [
|
||||||
'nas': [Nas._meta.verbose_name, Nas.objects.count()],
|
Domain._meta.verbose_name,
|
||||||
|
Domain.objects.exclude(cname=None).count(),
|
||||||
|
],
|
||||||
|
"iplist": [IpList._meta.verbose_name, IpList.objects.count()],
|
||||||
|
"service": [Service._meta.verbose_name, Service.objects.count()],
|
||||||
|
"ouvertureportlist": [
|
||||||
|
OuverturePortList._meta.verbose_name,
|
||||||
|
OuverturePortList.objects.count(),
|
||||||
|
],
|
||||||
|
"vlan": [Vlan._meta.verbose_name, Vlan.objects.count()],
|
||||||
|
"SOA": [SOA._meta.verbose_name, SOA.objects.count()],
|
||||||
|
"Mx": [Mx._meta.verbose_name, Mx.objects.count()],
|
||||||
|
"Ns": [Ns._meta.verbose_name, Ns.objects.count()],
|
||||||
|
"nas": [Nas._meta.verbose_name, Nas.objects.count()],
|
||||||
},
|
},
|
||||||
_("Topology"): {
|
_("Topology"): {
|
||||||
'switch': [Switch._meta.verbose_name,
|
"switch": [Switch._meta.verbose_name, Switch.objects.count()],
|
||||||
Switch.objects.count()],
|
"bornes": [AccessPoint._meta.verbose_name, AccessPoint.objects.count()],
|
||||||
'bornes': [AccessPoint._meta.verbose_name,
|
"port": [Port._meta.verbose_name, Port.objects.count()],
|
||||||
AccessPoint.objects.count()],
|
"chambre": [Room._meta.verbose_name, Room.objects.count()],
|
||||||
'port': [Port._meta.verbose_name, Port.objects.count()],
|
"stack": [Stack._meta.verbose_name, Stack.objects.count()],
|
||||||
'chambre': [Room._meta.verbose_name, Room.objects.count()],
|
"modelswitch": [
|
||||||
'stack': [Stack._meta.verbose_name, Stack.objects.count()],
|
|
||||||
'modelswitch': [
|
|
||||||
ModelSwitch._meta.verbose_name,
|
ModelSwitch._meta.verbose_name,
|
||||||
ModelSwitch.objects.count()
|
ModelSwitch.objects.count(),
|
||||||
],
|
],
|
||||||
'constructorswitch': [
|
"constructorswitch": [
|
||||||
ConstructorSwitch._meta.verbose_name,
|
ConstructorSwitch._meta.verbose_name,
|
||||||
ConstructorSwitch.objects.count()
|
ConstructorSwitch.objects.count(),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
_("Actions performed"):
|
_("Actions performed"): {
|
||||||
{
|
"revision": [_("Number of actions"), Revision.objects.count()]
|
||||||
'revision': [_("Number of actions"), Revision.objects.count()],
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return render(request, 'logs/stats_models.html', {'stats_list': stats})
|
return render(request, "logs/stats_models.html", {"stats_list": stats})
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@can_view_app('users')
|
@can_view_app("users")
|
||||||
def stats_users(request):
|
def stats_users(request):
|
||||||
"""Affiche les statistiques base de données aggrégées par user :
|
"""Affiche les statistiques base de données aggrégées par user :
|
||||||
nombre de machines par user, d'etablissements par user,
|
nombre de machines par user, d'etablissements par user,
|
||||||
|
@ -434,55 +413,51 @@ def stats_users(request):
|
||||||
de bannissement par user, etc"""
|
de bannissement par user, etc"""
|
||||||
stats = {
|
stats = {
|
||||||
_("User"): {
|
_("User"): {
|
||||||
_("Machines"): User.objects.annotate(
|
_("Machines"): User.objects.annotate(num=Count("machine")).order_by("-num")[
|
||||||
num=Count('machine')
|
:10
|
||||||
).order_by('-num')[:10],
|
],
|
||||||
_("Invoice"): User.objects.annotate(
|
_("Invoice"): User.objects.annotate(num=Count("facture")).order_by("-num")[
|
||||||
num=Count('facture')
|
:10
|
||||||
).order_by('-num')[:10],
|
],
|
||||||
_("Ban"): User.objects.annotate(
|
_("Ban"): User.objects.annotate(num=Count("ban")).order_by("-num")[:10],
|
||||||
num=Count('ban')
|
_("Whitelist"): User.objects.annotate(num=Count("whitelist")).order_by(
|
||||||
).order_by('-num')[:10],
|
"-num"
|
||||||
_("Whitelist"): User.objects.annotate(
|
)[:10],
|
||||||
num=Count('whitelist')
|
_("Rights"): User.objects.annotate(num=Count("groups")).order_by("-num")[
|
||||||
).order_by('-num')[:10],
|
:10
|
||||||
_("Rights"): User.objects.annotate(
|
],
|
||||||
num=Count('groups')
|
|
||||||
).order_by('-num')[:10],
|
|
||||||
},
|
},
|
||||||
_("School"): {
|
_("School"): {
|
||||||
_("User"): School.objects.annotate(
|
_("User"): School.objects.annotate(num=Count("user")).order_by("-num")[:10]
|
||||||
num=Count('user')
|
|
||||||
).order_by('-num')[:10],
|
|
||||||
},
|
},
|
||||||
_("Payment method"): {
|
_("Payment method"): {
|
||||||
_("User"): Paiement.objects.annotate(
|
_("User"): Paiement.objects.annotate(num=Count("facture")).order_by("-num")[
|
||||||
num=Count('facture')
|
:10
|
||||||
).order_by('-num')[:10],
|
]
|
||||||
},
|
},
|
||||||
_("Bank"): {
|
_("Bank"): {
|
||||||
_("User"): Banque.objects.annotate(
|
_("User"): Banque.objects.annotate(num=Count("facture")).order_by("-num")[
|
||||||
num=Count('facture')
|
:10
|
||||||
).order_by('-num')[:10],
|
]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return render(request, 'logs/stats_users.html', {'stats_list': stats})
|
return render(request, "logs/stats_users.html", {"stats_list": stats})
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@can_view_app('users')
|
@can_view_app("users")
|
||||||
def stats_actions(request):
|
def stats_actions(request):
|
||||||
"""Vue qui affiche les statistiques de modifications d'objets par
|
"""Vue qui affiche les statistiques de modifications d'objets par
|
||||||
utilisateurs.
|
utilisateurs.
|
||||||
Affiche le nombre de modifications aggrégées par utilisateurs"""
|
Affiche le nombre de modifications aggrégées par utilisateurs"""
|
||||||
stats = {
|
stats = {
|
||||||
_("User"): {
|
_("User"): {
|
||||||
_("Action"): User.objects.annotate(
|
_("Action"): User.objects.annotate(num=Count("revision")).order_by("-num")[
|
||||||
num=Count('revision')
|
:40
|
||||||
).order_by('-num')[:40],
|
]
|
||||||
},
|
|
||||||
}
|
}
|
||||||
return render(request, 'logs/stats_users.html', {'stats_list': stats})
|
}
|
||||||
|
return render(request, "logs/stats_users.html", {"stats_list": stats})
|
||||||
|
|
||||||
|
|
||||||
def history(request, application, object_name, object_id):
|
def history(request, application, object_name, object_id):
|
||||||
|
@ -509,33 +484,29 @@ def history(request, application, object_name, object_id):
|
||||||
model = apps.get_model(application, object_name)
|
model = apps.get_model(application, object_name)
|
||||||
except LookupError:
|
except LookupError:
|
||||||
raise Http404(_("No model found."))
|
raise Http404(_("No model found."))
|
||||||
object_name_id = object_name + 'id'
|
object_name_id = object_name + "id"
|
||||||
kwargs = {object_name_id: object_id}
|
kwargs = {object_name_id: object_id}
|
||||||
try:
|
try:
|
||||||
instance = model.get_instance(**kwargs)
|
instance = model.get_instance(**kwargs)
|
||||||
except model.DoesNotExist:
|
except model.DoesNotExist:
|
||||||
messages.error(request, _("Nonexistent entry."))
|
messages.error(request, _("Nonexistent entry."))
|
||||||
return redirect(reverse(
|
return redirect(
|
||||||
'users:profil',
|
reverse("users:profil", kwargs={"userid": str(request.user.id)})
|
||||||
kwargs={'userid': str(request.user.id)}
|
)
|
||||||
))
|
|
||||||
can, msg, _permissions = instance.can_view(request.user)
|
can, msg, _permissions = instance.can_view(request.user)
|
||||||
if not can:
|
if not can:
|
||||||
messages.error(request, msg or _("You don't have the right to access this menu."))
|
messages.error(
|
||||||
return redirect(reverse(
|
request, msg or _("You don't have the right to access this menu.")
|
||||||
'users:profil',
|
)
|
||||||
kwargs={'userid': str(request.user.id)}
|
return redirect(
|
||||||
))
|
reverse("users:profil", kwargs={"userid": str(request.user.id)})
|
||||||
pagination_number = GeneralOption.get_cached_value('pagination_number')
|
)
|
||||||
|
pagination_number = GeneralOption.get_cached_value("pagination_number")
|
||||||
reversions = Version.objects.get_for_object(instance)
|
reversions = Version.objects.get_for_object(instance)
|
||||||
if hasattr(instance, 'linked_objects'):
|
if hasattr(instance, "linked_objects"):
|
||||||
for related_object in chain(instance.linked_objects()):
|
for related_object in chain(instance.linked_objects()):
|
||||||
reversions = (reversions |
|
reversions = reversions | Version.objects.get_for_object(related_object)
|
||||||
Version.objects.get_for_object(related_object))
|
|
||||||
reversions = re2o_paginator(request, reversions, pagination_number)
|
reversions = re2o_paginator(request, reversions, pagination_number)
|
||||||
return render(
|
return render(
|
||||||
request,
|
request, "re2o/history.html", {"reversions": reversions, "object": instance}
|
||||||
're2o/history.html',
|
|
||||||
{'reversions': reversions, 'object': instance}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -38,11 +38,9 @@ def can_view(user):
|
||||||
A couple (allowed, msg) where allowed is a boolean which is True if
|
A couple (allowed, msg) where allowed is a boolean which is True if
|
||||||
viewing is granted and msg is a message (can be None).
|
viewing is granted and msg is a message (can be None).
|
||||||
"""
|
"""
|
||||||
can = user.has_module_perms('machines')
|
can = user.has_module_perms("machines")
|
||||||
return (
|
return (
|
||||||
can,
|
can,
|
||||||
None if can else _("You don't have the right to view this"
|
None if can else _("You don't have the right to view this" " application."),
|
||||||
" application."),
|
("machines",),
|
||||||
('machines',)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -51,106 +51,127 @@ from .models import IpType, Machine, MachineType, Domain, IpList, Interface
|
||||||
|
|
||||||
class MachineAdmin(VersionAdmin):
|
class MachineAdmin(VersionAdmin):
|
||||||
""" Admin view of a Machine object """
|
""" Admin view of a Machine object """
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Ipv6ListAdmin(VersionAdmin):
|
class Ipv6ListAdmin(VersionAdmin):
|
||||||
""" Admin view of a Ipv6List object """
|
""" Admin view of a Ipv6List object """
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class IpTypeAdmin(VersionAdmin):
|
class IpTypeAdmin(VersionAdmin):
|
||||||
""" Admin view of a IpType object """
|
""" Admin view of a IpType object """
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class MachineTypeAdmin(VersionAdmin):
|
class MachineTypeAdmin(VersionAdmin):
|
||||||
""" Admin view of a MachineType object """
|
""" Admin view of a MachineType object """
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class VlanAdmin(VersionAdmin):
|
class VlanAdmin(VersionAdmin):
|
||||||
""" Admin view of a Vlan object """
|
""" Admin view of a Vlan object """
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ExtensionAdmin(VersionAdmin):
|
class ExtensionAdmin(VersionAdmin):
|
||||||
""" Admin view of a Extension object """
|
""" Admin view of a Extension object """
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class SOAAdmin(VersionAdmin):
|
class SOAAdmin(VersionAdmin):
|
||||||
""" Admin view of a SOA object """
|
""" Admin view of a SOA object """
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class MxAdmin(VersionAdmin):
|
class MxAdmin(VersionAdmin):
|
||||||
""" Admin view of a MX object """
|
""" Admin view of a MX object """
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class NsAdmin(VersionAdmin):
|
class NsAdmin(VersionAdmin):
|
||||||
""" Admin view of a NS object """
|
""" Admin view of a NS object """
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class TxtAdmin(VersionAdmin):
|
class TxtAdmin(VersionAdmin):
|
||||||
""" Admin view of a TXT object """
|
""" Admin view of a TXT object """
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class DNameAdmin(VersionAdmin):
|
class DNameAdmin(VersionAdmin):
|
||||||
""" Admin view of a DName object """
|
""" Admin view of a DName object """
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class SrvAdmin(VersionAdmin):
|
class SrvAdmin(VersionAdmin):
|
||||||
""" Admin view of a SRV object """
|
""" Admin view of a SRV object """
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class SshFpAdmin(VersionAdmin):
|
class SshFpAdmin(VersionAdmin):
|
||||||
""" Admin view of a SSHFP object """
|
""" Admin view of a SSHFP object """
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class NasAdmin(VersionAdmin):
|
class NasAdmin(VersionAdmin):
|
||||||
""" Admin view of a Nas object """
|
""" Admin view of a Nas object """
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class IpListAdmin(VersionAdmin):
|
class IpListAdmin(VersionAdmin):
|
||||||
""" Admin view of a Ipv4List object """
|
""" Admin view of a Ipv4List object """
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class OuverturePortAdmin(VersionAdmin):
|
class OuverturePortAdmin(VersionAdmin):
|
||||||
""" Admin view of a OuverturePort object """
|
""" Admin view of a OuverturePort object """
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class OuverturePortListAdmin(VersionAdmin):
|
class OuverturePortListAdmin(VersionAdmin):
|
||||||
""" Admin view of a OuverturePortList object """
|
""" Admin view of a OuverturePortList object """
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class InterfaceAdmin(VersionAdmin):
|
class InterfaceAdmin(VersionAdmin):
|
||||||
""" Admin view of a Interface object """
|
""" Admin view of a Interface object """
|
||||||
list_display = ('machine', 'machine_type', 'mac_address', 'ipv4', 'details')
|
|
||||||
|
list_display = ("machine", "machine_type", "mac_address", "ipv4", "details")
|
||||||
|
|
||||||
|
|
||||||
class DomainAdmin(VersionAdmin):
|
class DomainAdmin(VersionAdmin):
|
||||||
""" Admin view of a Domain object """
|
""" Admin view of a Domain object """
|
||||||
list_display = ('interface_parent', 'name', 'extension', 'cname')
|
|
||||||
|
list_display = ("interface_parent", "name", "extension", "cname")
|
||||||
|
|
||||||
|
|
||||||
class ServiceAdmin(VersionAdmin):
|
class ServiceAdmin(VersionAdmin):
|
||||||
""" Admin view of a ServiceAdmin object """
|
""" Admin view of a ServiceAdmin object """
|
||||||
list_display = ('service_type', 'min_time_regen', 'regular_time_regen')
|
|
||||||
|
list_display = ("service_type", "min_time_regen", "regular_time_regen")
|
||||||
|
|
||||||
|
|
||||||
class RoleAdmin(VersionAdmin):
|
class RoleAdmin(VersionAdmin):
|
||||||
""" Admin view of a RoleAdmin object """
|
""" Admin view of a RoleAdmin object """
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -70,19 +70,19 @@ class EditMachineForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Machine
|
model = Machine
|
||||||
fields = '__all__'
|
fields = "__all__"
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
super(EditMachineForm, self).__init__(*args, prefix=prefix, **kwargs)
|
super(EditMachineForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
self.fields['name'].label = _("Machine name")
|
self.fields["name"].label = _("Machine name")
|
||||||
|
|
||||||
|
|
||||||
class NewMachineForm(EditMachineForm):
|
class NewMachineForm(EditMachineForm):
|
||||||
"""Creation d'une machine, ne renseigne que le nom"""
|
"""Creation d'une machine, ne renseigne que le nom"""
|
||||||
|
|
||||||
class Meta(EditMachineForm.Meta):
|
class Meta(EditMachineForm.Meta):
|
||||||
fields = ['name']
|
fields = ["name"]
|
||||||
|
|
||||||
|
|
||||||
class EditInterfaceForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
class EditInterfaceForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
||||||
|
@ -90,39 +90,38 @@ class EditInterfaceForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Interface
|
model = Interface
|
||||||
fields = ['machine', 'machine_type', 'ipv4', 'mac_address', 'details']
|
fields = ["machine", "machine_type", "ipv4", "mac_address", "details"]
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
user = kwargs.get('user')
|
user = kwargs.get("user")
|
||||||
super(EditInterfaceForm, self).__init__(*args, prefix=prefix, **kwargs)
|
super(EditInterfaceForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
self.fields['mac_address'].label = _("MAC address")
|
self.fields["mac_address"].label = _("MAC address")
|
||||||
self.fields['machine_type'].label = _("Machine type")
|
self.fields["machine_type"].label = _("Machine type")
|
||||||
self.fields['machine_type'].empty_label = _("Select a machine type")
|
self.fields["machine_type"].empty_label = _("Select a machine type")
|
||||||
if "ipv4" in self.fields:
|
if "ipv4" in self.fields:
|
||||||
self.fields['ipv4'].empty_label = _("Automatic IPv4 assignment")
|
self.fields["ipv4"].empty_label = _("Automatic IPv4 assignment")
|
||||||
self.fields['ipv4'].queryset = IpList.objects.filter(
|
self.fields["ipv4"].queryset = IpList.objects.filter(interface__isnull=True)
|
||||||
interface__isnull=True
|
|
||||||
)
|
|
||||||
can_use_all_iptype, _reason, _permissions = IpType.can_use_all(user)
|
can_use_all_iptype, _reason, _permissions = IpType.can_use_all(user)
|
||||||
if not can_use_all_iptype:
|
if not can_use_all_iptype:
|
||||||
self.fields['ipv4'].queryset = IpList.objects.filter(
|
self.fields["ipv4"].queryset = IpList.objects.filter(
|
||||||
interface__isnull=True
|
interface__isnull=True
|
||||||
).filter(ip_type__in=IpType.objects.filter(need_infra=False))
|
).filter(ip_type__in=IpType.objects.filter(need_infra=False))
|
||||||
else:
|
else:
|
||||||
self.fields['ipv4'].queryset = IpList.objects.filter(
|
self.fields["ipv4"].queryset = IpList.objects.filter(
|
||||||
interface__isnull=True
|
interface__isnull=True
|
||||||
)
|
)
|
||||||
# Add it's own address
|
# Add it's own address
|
||||||
self.fields['ipv4'].queryset |= IpList.objects.filter(
|
self.fields["ipv4"].queryset |= IpList.objects.filter(
|
||||||
interface=self.instance
|
interface=self.instance
|
||||||
)
|
)
|
||||||
if "machine" in self.fields:
|
if "machine" in self.fields:
|
||||||
self.fields['machine'].queryset = Machine.objects.all() \
|
self.fields["machine"].queryset = Machine.objects.all().select_related(
|
||||||
.select_related('user')
|
"user"
|
||||||
|
)
|
||||||
can_use_all_machinetype, _reason, _permissions = MachineType.can_use_all(user)
|
can_use_all_machinetype, _reason, _permissions = MachineType.can_use_all(user)
|
||||||
if not can_use_all_machinetype:
|
if not can_use_all_machinetype:
|
||||||
self.fields['machine_type'].queryset = MachineType.objects.filter(
|
self.fields["machine_type"].queryset = MachineType.objects.filter(
|
||||||
ip_type__in=IpType.objects.filter(need_infra=False)
|
ip_type__in=IpType.objects.filter(need_infra=False)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -132,7 +131,7 @@ class AddInterfaceForm(EditInterfaceForm):
|
||||||
affiche ou non l'ensemble des ip disponibles"""
|
affiche ou non l'ensemble des ip disponibles"""
|
||||||
|
|
||||||
class Meta(EditInterfaceForm.Meta):
|
class Meta(EditInterfaceForm.Meta):
|
||||||
fields = ['machine_type', 'ipv4', 'mac_address', 'details']
|
fields = ["machine_type", "ipv4", "mac_address", "details"]
|
||||||
|
|
||||||
|
|
||||||
class AliasForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
class AliasForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
||||||
|
@ -140,15 +139,15 @@ class AliasForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Domain
|
model = Domain
|
||||||
fields = ['name', 'extension', 'ttl']
|
fields = ["name", "extension", "ttl"]
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
user = kwargs['user']
|
user = kwargs["user"]
|
||||||
super(AliasForm, self).__init__(*args, prefix=prefix, **kwargs)
|
super(AliasForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
can_use_all, _reason, _permissions = Extension.can_use_all(user)
|
can_use_all, _reason, _permissions = Extension.can_use_all(user)
|
||||||
if not can_use_all:
|
if not can_use_all:
|
||||||
self.fields['extension'].queryset = Extension.objects.filter(
|
self.fields["extension"].queryset = Extension.objects.filter(
|
||||||
need_infra=False
|
need_infra=False
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -158,30 +157,31 @@ class DomainForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Domain
|
model = Domain
|
||||||
fields = ['name', 'ttl']
|
fields = ["name", "ttl"]
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
if 'user' in kwargs:
|
if "user" in kwargs:
|
||||||
user = kwargs['user']
|
user = kwargs["user"]
|
||||||
initial = kwargs.get('initial', {})
|
initial = kwargs.get("initial", {})
|
||||||
initial['name'] = user.get_next_domain_name()
|
initial["name"] = user.get_next_domain_name()
|
||||||
kwargs['initial'] = initial
|
kwargs["initial"] = initial
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
super(DomainForm, self).__init__(*args, prefix=prefix, **kwargs)
|
super(DomainForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class DelAliasForm(FormRevMixin, Form):
|
class DelAliasForm(FormRevMixin, Form):
|
||||||
"""Suppression d'un ou plusieurs objets alias"""
|
"""Suppression d'un ou plusieurs objets alias"""
|
||||||
|
|
||||||
alias = forms.ModelMultipleChoiceField(
|
alias = forms.ModelMultipleChoiceField(
|
||||||
queryset=Domain.objects.all(),
|
queryset=Domain.objects.all(),
|
||||||
label=_("Current aliases"),
|
label=_("Current aliases"),
|
||||||
widget=forms.CheckboxSelectMultiple
|
widget=forms.CheckboxSelectMultiple,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
interface = kwargs.pop('interface')
|
interface = kwargs.pop("interface")
|
||||||
super(DelAliasForm, self).__init__(*args, **kwargs)
|
super(DelAliasForm, self).__init__(*args, **kwargs)
|
||||||
self.fields['alias'].queryset = Domain.objects.filter(
|
self.fields["alias"].queryset = Domain.objects.filter(
|
||||||
cname__in=Domain.objects.filter(interface_parent=interface)
|
cname__in=Domain.objects.filter(interface_parent=interface)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -191,30 +191,31 @@ class MachineTypeForm(FormRevMixin, ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = MachineType
|
model = MachineType
|
||||||
fields = ['name', 'ip_type']
|
fields = ["name", "ip_type"]
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
super(MachineTypeForm, self).__init__(*args, prefix=prefix, **kwargs)
|
super(MachineTypeForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
self.fields['name'].label = _("Machine type to add")
|
self.fields["name"].label = _("Machine type to add")
|
||||||
self.fields['ip_type'].label = _("Related IP type")
|
self.fields["ip_type"].label = _("Related IP type")
|
||||||
|
|
||||||
|
|
||||||
class DelMachineTypeForm(FormRevMixin, Form):
|
class DelMachineTypeForm(FormRevMixin, Form):
|
||||||
"""Suppression d'un ou plusieurs machinetype"""
|
"""Suppression d'un ou plusieurs machinetype"""
|
||||||
|
|
||||||
machinetypes = forms.ModelMultipleChoiceField(
|
machinetypes = forms.ModelMultipleChoiceField(
|
||||||
queryset=MachineType.objects.none(),
|
queryset=MachineType.objects.none(),
|
||||||
label=_("Current machine types"),
|
label=_("Current machine types"),
|
||||||
widget=forms.CheckboxSelectMultiple
|
widget=forms.CheckboxSelectMultiple,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
instances = kwargs.pop('instances', None)
|
instances = kwargs.pop("instances", None)
|
||||||
super(DelMachineTypeForm, self).__init__(*args, **kwargs)
|
super(DelMachineTypeForm, self).__init__(*args, **kwargs)
|
||||||
if instances:
|
if instances:
|
||||||
self.fields['machinetypes'].queryset = instances
|
self.fields["machinetypes"].queryset = instances
|
||||||
else:
|
else:
|
||||||
self.fields['machinetypes'].queryset = MachineType.objects.all()
|
self.fields["machinetypes"].queryset = MachineType.objects.all()
|
||||||
|
|
||||||
|
|
||||||
class IpTypeForm(FormRevMixin, ModelForm):
|
class IpTypeForm(FormRevMixin, ModelForm):
|
||||||
|
@ -223,12 +224,12 @@ class IpTypeForm(FormRevMixin, ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = IpType
|
model = IpType
|
||||||
fields = '__all__'
|
fields = "__all__"
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
super(IpTypeForm, self).__init__(*args, prefix=prefix, **kwargs)
|
super(IpTypeForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
self.fields['name'].label = _("IP type to add")
|
self.fields["name"].label = _("IP type to add")
|
||||||
|
|
||||||
|
|
||||||
class EditIpTypeForm(IpTypeForm):
|
class EditIpTypeForm(IpTypeForm):
|
||||||
|
@ -236,27 +237,37 @@ class EditIpTypeForm(IpTypeForm):
|
||||||
synchroniser les objets iplist"""
|
synchroniser les objets iplist"""
|
||||||
|
|
||||||
class Meta(IpTypeForm.Meta):
|
class Meta(IpTypeForm.Meta):
|
||||||
fields = ['extension', 'name', 'need_infra', 'domaine_ip_network', 'domaine_ip_netmask',
|
fields = [
|
||||||
'prefix_v6', 'prefix_v6_length',
|
"extension",
|
||||||
'vlan', 'reverse_v4', 'reverse_v6',
|
"name",
|
||||||
'ouverture_ports']
|
"need_infra",
|
||||||
|
"domaine_ip_network",
|
||||||
|
"domaine_ip_netmask",
|
||||||
|
"prefix_v6",
|
||||||
|
"prefix_v6_length",
|
||||||
|
"vlan",
|
||||||
|
"reverse_v4",
|
||||||
|
"reverse_v6",
|
||||||
|
"ouverture_ports",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class DelIpTypeForm(FormRevMixin, Form):
|
class DelIpTypeForm(FormRevMixin, Form):
|
||||||
"""Suppression d'un ou plusieurs iptype"""
|
"""Suppression d'un ou plusieurs iptype"""
|
||||||
|
|
||||||
iptypes = forms.ModelMultipleChoiceField(
|
iptypes = forms.ModelMultipleChoiceField(
|
||||||
queryset=IpType.objects.none(),
|
queryset=IpType.objects.none(),
|
||||||
label=_("Current IP types"),
|
label=_("Current IP types"),
|
||||||
widget=forms.CheckboxSelectMultiple
|
widget=forms.CheckboxSelectMultiple,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
instances = kwargs.pop('instances', None)
|
instances = kwargs.pop("instances", None)
|
||||||
super(DelIpTypeForm, self).__init__(*args, **kwargs)
|
super(DelIpTypeForm, self).__init__(*args, **kwargs)
|
||||||
if instances:
|
if instances:
|
||||||
self.fields['iptypes'].queryset = instances
|
self.fields["iptypes"].queryset = instances
|
||||||
else:
|
else:
|
||||||
self.fields['iptypes'].queryset = IpType.objects.all()
|
self.fields["iptypes"].queryset = IpType.objects.all()
|
||||||
|
|
||||||
|
|
||||||
class ExtensionForm(FormRevMixin, ModelForm):
|
class ExtensionForm(FormRevMixin, ModelForm):
|
||||||
|
@ -264,33 +275,34 @@ class ExtensionForm(FormRevMixin, ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Extension
|
model = Extension
|
||||||
fields = '__all__'
|
fields = "__all__"
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
super(ExtensionForm, self).__init__(*args, prefix=prefix, **kwargs)
|
super(ExtensionForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
self.fields['name'].label = _("Extension to add")
|
self.fields["name"].label = _("Extension to add")
|
||||||
self.fields['origin'].label = _("A record origin")
|
self.fields["origin"].label = _("A record origin")
|
||||||
self.fields['origin_v6'].label = _("AAAA record origin")
|
self.fields["origin_v6"].label = _("AAAA record origin")
|
||||||
self.fields['soa'].label = _("SOA record to use")
|
self.fields["soa"].label = _("SOA record to use")
|
||||||
self.fields['dnssec'].label = _("Sign with DNSSEC")
|
self.fields["dnssec"].label = _("Sign with DNSSEC")
|
||||||
|
|
||||||
|
|
||||||
class DelExtensionForm(FormRevMixin, Form):
|
class DelExtensionForm(FormRevMixin, Form):
|
||||||
"""Suppression d'une ou plusieurs extensions"""
|
"""Suppression d'une ou plusieurs extensions"""
|
||||||
|
|
||||||
extensions = forms.ModelMultipleChoiceField(
|
extensions = forms.ModelMultipleChoiceField(
|
||||||
queryset=Extension.objects.none(),
|
queryset=Extension.objects.none(),
|
||||||
label=_("Current extensions"),
|
label=_("Current extensions"),
|
||||||
widget=forms.CheckboxSelectMultiple
|
widget=forms.CheckboxSelectMultiple,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
instances = kwargs.pop('instances', None)
|
instances = kwargs.pop("instances", None)
|
||||||
super(DelExtensionForm, self).__init__(*args, **kwargs)
|
super(DelExtensionForm, self).__init__(*args, **kwargs)
|
||||||
if instances:
|
if instances:
|
||||||
self.fields['extensions'].queryset = instances
|
self.fields["extensions"].queryset = instances
|
||||||
else:
|
else:
|
||||||
self.fields['extensions'].queryset = Extension.objects.all()
|
self.fields["extensions"].queryset = Extension.objects.all()
|
||||||
|
|
||||||
|
|
||||||
class Ipv6ListForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
class Ipv6ListForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
||||||
|
@ -298,10 +310,10 @@ class Ipv6ListForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Ipv6List
|
model = Ipv6List
|
||||||
fields = ['ipv6', 'slaac_ip']
|
fields = ["ipv6", "slaac_ip"]
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
super(Ipv6ListForm, self).__init__(*args, prefix=prefix, **kwargs)
|
super(Ipv6ListForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@ -310,28 +322,29 @@ class SOAForm(FormRevMixin, ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SOA
|
model = SOA
|
||||||
fields = '__all__'
|
fields = "__all__"
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
super(SOAForm, self).__init__(*args, prefix=prefix, **kwargs)
|
super(SOAForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class DelSOAForm(FormRevMixin, Form):
|
class DelSOAForm(FormRevMixin, Form):
|
||||||
"""Suppression d'un ou plusieurs SOA"""
|
"""Suppression d'un ou plusieurs SOA"""
|
||||||
|
|
||||||
soa = forms.ModelMultipleChoiceField(
|
soa = forms.ModelMultipleChoiceField(
|
||||||
queryset=SOA.objects.none(),
|
queryset=SOA.objects.none(),
|
||||||
label=_("Current SOA records"),
|
label=_("Current SOA records"),
|
||||||
widget=forms.CheckboxSelectMultiple
|
widget=forms.CheckboxSelectMultiple,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
instances = kwargs.pop('instances', None)
|
instances = kwargs.pop("instances", None)
|
||||||
super(DelSOAForm, self).__init__(*args, **kwargs)
|
super(DelSOAForm, self).__init__(*args, **kwargs)
|
||||||
if instances:
|
if instances:
|
||||||
self.fields['soa'].queryset = instances
|
self.fields["soa"].queryset = instances
|
||||||
else:
|
else:
|
||||||
self.fields['soa'].queryset = SOA.objects.all()
|
self.fields["soa"].queryset = SOA.objects.all()
|
||||||
|
|
||||||
|
|
||||||
class MxForm(FormRevMixin, ModelForm):
|
class MxForm(FormRevMixin, ModelForm):
|
||||||
|
@ -339,31 +352,32 @@ class MxForm(FormRevMixin, ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Mx
|
model = Mx
|
||||||
fields = ['zone', 'priority', 'name', 'ttl']
|
fields = ["zone", "priority", "name", "ttl"]
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
super(MxForm, self).__init__(*args, prefix=prefix, **kwargs)
|
super(MxForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
self.fields['name'].queryset = Domain.objects.exclude(
|
self.fields["name"].queryset = Domain.objects.exclude(
|
||||||
interface_parent=None
|
interface_parent=None
|
||||||
).select_related('extension')
|
).select_related("extension")
|
||||||
|
|
||||||
|
|
||||||
class DelMxForm(FormRevMixin, Form):
|
class DelMxForm(FormRevMixin, Form):
|
||||||
"""Suppression d'un ou plusieurs MX"""
|
"""Suppression d'un ou plusieurs MX"""
|
||||||
|
|
||||||
mx = forms.ModelMultipleChoiceField(
|
mx = forms.ModelMultipleChoiceField(
|
||||||
queryset=Mx.objects.none(),
|
queryset=Mx.objects.none(),
|
||||||
label=_("Current MX records"),
|
label=_("Current MX records"),
|
||||||
widget=forms.CheckboxSelectMultiple
|
widget=forms.CheckboxSelectMultiple,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
instances = kwargs.pop('instances', None)
|
instances = kwargs.pop("instances", None)
|
||||||
super(DelMxForm, self).__init__(*args, **kwargs)
|
super(DelMxForm, self).__init__(*args, **kwargs)
|
||||||
if instances:
|
if instances:
|
||||||
self.fields['mx'].queryset = instances
|
self.fields["mx"].queryset = instances
|
||||||
else:
|
else:
|
||||||
self.fields['mx'].queryset = Mx.objects.all()
|
self.fields["mx"].queryset = Mx.objects.all()
|
||||||
|
|
||||||
|
|
||||||
class NsForm(FormRevMixin, ModelForm):
|
class NsForm(FormRevMixin, ModelForm):
|
||||||
|
@ -373,31 +387,32 @@ class NsForm(FormRevMixin, ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Ns
|
model = Ns
|
||||||
fields = ['zone', 'ns', 'ttl']
|
fields = ["zone", "ns", "ttl"]
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
super(NsForm, self).__init__(*args, prefix=prefix, **kwargs)
|
super(NsForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
self.fields['ns'].queryset = Domain.objects.exclude(
|
self.fields["ns"].queryset = Domain.objects.exclude(
|
||||||
interface_parent=None
|
interface_parent=None
|
||||||
).select_related('extension')
|
).select_related("extension")
|
||||||
|
|
||||||
|
|
||||||
class DelNsForm(FormRevMixin, Form):
|
class DelNsForm(FormRevMixin, Form):
|
||||||
"""Suppresion d'un ou plusieurs NS"""
|
"""Suppresion d'un ou plusieurs NS"""
|
||||||
|
|
||||||
ns = forms.ModelMultipleChoiceField(
|
ns = forms.ModelMultipleChoiceField(
|
||||||
queryset=Ns.objects.none(),
|
queryset=Ns.objects.none(),
|
||||||
label=_("Current NS records"),
|
label=_("Current NS records"),
|
||||||
widget=forms.CheckboxSelectMultiple
|
widget=forms.CheckboxSelectMultiple,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
instances = kwargs.pop('instances', None)
|
instances = kwargs.pop("instances", None)
|
||||||
super(DelNsForm, self).__init__(*args, **kwargs)
|
super(DelNsForm, self).__init__(*args, **kwargs)
|
||||||
if instances:
|
if instances:
|
||||||
self.fields['ns'].queryset = instances
|
self.fields["ns"].queryset = instances
|
||||||
else:
|
else:
|
||||||
self.fields['ns'].queryset = Ns.objects.all()
|
self.fields["ns"].queryset = Ns.objects.all()
|
||||||
|
|
||||||
|
|
||||||
class TxtForm(FormRevMixin, ModelForm):
|
class TxtForm(FormRevMixin, ModelForm):
|
||||||
|
@ -405,28 +420,29 @@ class TxtForm(FormRevMixin, ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Txt
|
model = Txt
|
||||||
fields = '__all__'
|
fields = "__all__"
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
super(TxtForm, self).__init__(*args, prefix=prefix, **kwargs)
|
super(TxtForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class DelTxtForm(FormRevMixin, Form):
|
class DelTxtForm(FormRevMixin, Form):
|
||||||
"""Suppression d'un ou plusieurs TXT"""
|
"""Suppression d'un ou plusieurs TXT"""
|
||||||
|
|
||||||
txt = forms.ModelMultipleChoiceField(
|
txt = forms.ModelMultipleChoiceField(
|
||||||
queryset=Txt.objects.none(),
|
queryset=Txt.objects.none(),
|
||||||
label=_("Current TXT records"),
|
label=_("Current TXT records"),
|
||||||
widget=forms.CheckboxSelectMultiple
|
widget=forms.CheckboxSelectMultiple,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
instances = kwargs.pop('instances', None)
|
instances = kwargs.pop("instances", None)
|
||||||
super(DelTxtForm, self).__init__(*args, **kwargs)
|
super(DelTxtForm, self).__init__(*args, **kwargs)
|
||||||
if instances:
|
if instances:
|
||||||
self.fields['txt'].queryset = instances
|
self.fields["txt"].queryset = instances
|
||||||
else:
|
else:
|
||||||
self.fields['txt'].queryset = Txt.objects.all()
|
self.fields["txt"].queryset = Txt.objects.all()
|
||||||
|
|
||||||
|
|
||||||
class DNameForm(FormRevMixin, ModelForm):
|
class DNameForm(FormRevMixin, ModelForm):
|
||||||
|
@ -434,28 +450,29 @@ class DNameForm(FormRevMixin, ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = DName
|
model = DName
|
||||||
fields = '__all__'
|
fields = "__all__"
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
super(DNameForm, self).__init__(*args, prefix=prefix, **kwargs)
|
super(DNameForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class DelDNameForm(FormRevMixin, Form):
|
class DelDNameForm(FormRevMixin, Form):
|
||||||
"""Delete a set of DNAME entries"""
|
"""Delete a set of DNAME entries"""
|
||||||
|
|
||||||
dnames = forms.ModelMultipleChoiceField(
|
dnames = forms.ModelMultipleChoiceField(
|
||||||
queryset=Txt.objects.none(),
|
queryset=Txt.objects.none(),
|
||||||
label=_("Current DNAME records"),
|
label=_("Current DNAME records"),
|
||||||
widget=forms.CheckboxSelectMultiple
|
widget=forms.CheckboxSelectMultiple,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
instances = kwargs.pop('instances', None)
|
instances = kwargs.pop("instances", None)
|
||||||
super(DelDNameForm, self).__init__(*args, **kwargs)
|
super(DelDNameForm, self).__init__(*args, **kwargs)
|
||||||
if instances:
|
if instances:
|
||||||
self.fields['dnames'].queryset = instances
|
self.fields["dnames"].queryset = instances
|
||||||
else:
|
else:
|
||||||
self.fields['dnames'].queryset = DName.objects.all()
|
self.fields["dnames"].queryset = DName.objects.all()
|
||||||
|
|
||||||
|
|
||||||
class SrvForm(FormRevMixin, ModelForm):
|
class SrvForm(FormRevMixin, ModelForm):
|
||||||
|
@ -463,28 +480,29 @@ class SrvForm(FormRevMixin, ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Srv
|
model = Srv
|
||||||
fields = '__all__'
|
fields = "__all__"
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
super(SrvForm, self).__init__(*args, prefix=prefix, **kwargs)
|
super(SrvForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class DelSrvForm(FormRevMixin, Form):
|
class DelSrvForm(FormRevMixin, Form):
|
||||||
"""Suppression d'un ou plusieurs Srv"""
|
"""Suppression d'un ou plusieurs Srv"""
|
||||||
|
|
||||||
srv = forms.ModelMultipleChoiceField(
|
srv = forms.ModelMultipleChoiceField(
|
||||||
queryset=Srv.objects.none(),
|
queryset=Srv.objects.none(),
|
||||||
label=_("Current SRV records"),
|
label=_("Current SRV records"),
|
||||||
widget=forms.CheckboxSelectMultiple
|
widget=forms.CheckboxSelectMultiple,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
instances = kwargs.pop('instances', None)
|
instances = kwargs.pop("instances", None)
|
||||||
super(DelSrvForm, self).__init__(*args, **kwargs)
|
super(DelSrvForm, self).__init__(*args, **kwargs)
|
||||||
if instances:
|
if instances:
|
||||||
self.fields['srv'].queryset = instances
|
self.fields["srv"].queryset = instances
|
||||||
else:
|
else:
|
||||||
self.fields['srv'].queryset = Srv.objects.all()
|
self.fields["srv"].queryset = Srv.objects.all()
|
||||||
|
|
||||||
|
|
||||||
class NasForm(FormRevMixin, ModelForm):
|
class NasForm(FormRevMixin, ModelForm):
|
||||||
|
@ -493,28 +511,29 @@ class NasForm(FormRevMixin, ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Nas
|
model = Nas
|
||||||
fields = '__all__'
|
fields = "__all__"
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
super(NasForm, self).__init__(*args, prefix=prefix, **kwargs)
|
super(NasForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class DelNasForm(FormRevMixin, Form):
|
class DelNasForm(FormRevMixin, Form):
|
||||||
"""Suppression d'un ou plusieurs nas"""
|
"""Suppression d'un ou plusieurs nas"""
|
||||||
|
|
||||||
nas = forms.ModelMultipleChoiceField(
|
nas = forms.ModelMultipleChoiceField(
|
||||||
queryset=Nas.objects.none(),
|
queryset=Nas.objects.none(),
|
||||||
label=_("Current NAS devices"),
|
label=_("Current NAS devices"),
|
||||||
widget=forms.CheckboxSelectMultiple
|
widget=forms.CheckboxSelectMultiple,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
instances = kwargs.pop('instances', None)
|
instances = kwargs.pop("instances", None)
|
||||||
super(DelNasForm, self).__init__(*args, **kwargs)
|
super(DelNasForm, self).__init__(*args, **kwargs)
|
||||||
if instances:
|
if instances:
|
||||||
self.fields['nas'].queryset = instances
|
self.fields["nas"].queryset = instances
|
||||||
else:
|
else:
|
||||||
self.fields['nas'].queryset = Nas.objects.all()
|
self.fields["nas"].queryset = Nas.objects.all()
|
||||||
|
|
||||||
|
|
||||||
class RoleForm(FormRevMixin, ModelForm):
|
class RoleForm(FormRevMixin, ModelForm):
|
||||||
|
@ -522,32 +541,32 @@ class RoleForm(FormRevMixin, ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Role
|
model = Role
|
||||||
fields = '__all__'
|
fields = "__all__"
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
super(RoleForm, self).__init__(*args, prefix=prefix, **kwargs)
|
super(RoleForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
self.fields['servers'].queryset = (Interface.objects.all()
|
self.fields["servers"].queryset = Interface.objects.all().select_related(
|
||||||
.select_related(
|
"domain__extension"
|
||||||
'domain__extension'
|
)
|
||||||
))
|
|
||||||
|
|
||||||
|
|
||||||
class DelRoleForm(FormRevMixin, Form):
|
class DelRoleForm(FormRevMixin, Form):
|
||||||
"""Deletion of one or several roles."""
|
"""Deletion of one or several roles."""
|
||||||
|
|
||||||
role = forms.ModelMultipleChoiceField(
|
role = forms.ModelMultipleChoiceField(
|
||||||
queryset=Role.objects.none(),
|
queryset=Role.objects.none(),
|
||||||
label=_("Current roles"),
|
label=_("Current roles"),
|
||||||
widget=forms.CheckboxSelectMultiple
|
widget=forms.CheckboxSelectMultiple,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
instances = kwargs.pop('instances', None)
|
instances = kwargs.pop("instances", None)
|
||||||
super(DelRoleForm, self).__init__(*args, **kwargs)
|
super(DelRoleForm, self).__init__(*args, **kwargs)
|
||||||
if instances:
|
if instances:
|
||||||
self.fields['role'].queryset = instances
|
self.fields["role"].queryset = instances
|
||||||
else:
|
else:
|
||||||
self.fields['role'].queryset = Role.objects.all()
|
self.fields["role"].queryset = Role.objects.all()
|
||||||
|
|
||||||
|
|
||||||
class ServiceForm(FormRevMixin, ModelForm):
|
class ServiceForm(FormRevMixin, ModelForm):
|
||||||
|
@ -555,15 +574,14 @@ class ServiceForm(FormRevMixin, ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Service
|
model = Service
|
||||||
fields = '__all__'
|
fields = "__all__"
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
super(ServiceForm, self).__init__(*args, prefix=prefix, **kwargs)
|
super(ServiceForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
self.fields['servers'].queryset = (Interface.objects.all()
|
self.fields["servers"].queryset = Interface.objects.all().select_related(
|
||||||
.select_related(
|
"domain__extension"
|
||||||
'domain__extension'
|
)
|
||||||
))
|
|
||||||
|
|
||||||
def save(self, commit=True):
|
def save(self, commit=True):
|
||||||
# TODO : None of the parents of ServiceForm use the commit
|
# TODO : None of the parents of ServiceForm use the commit
|
||||||
|
@ -571,25 +589,26 @@ class ServiceForm(FormRevMixin, ModelForm):
|
||||||
instance = super(ServiceForm, self).save(commit=False)
|
instance = super(ServiceForm, self).save(commit=False)
|
||||||
if commit:
|
if commit:
|
||||||
instance.save()
|
instance.save()
|
||||||
instance.process_link(self.cleaned_data.get('servers'))
|
instance.process_link(self.cleaned_data.get("servers"))
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
|
|
||||||
class DelServiceForm(FormRevMixin, Form):
|
class DelServiceForm(FormRevMixin, Form):
|
||||||
"""Suppression d'un ou plusieurs service"""
|
"""Suppression d'un ou plusieurs service"""
|
||||||
|
|
||||||
service = forms.ModelMultipleChoiceField(
|
service = forms.ModelMultipleChoiceField(
|
||||||
queryset=Service.objects.none(),
|
queryset=Service.objects.none(),
|
||||||
label=_("Current services"),
|
label=_("Current services"),
|
||||||
widget=forms.CheckboxSelectMultiple
|
widget=forms.CheckboxSelectMultiple,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
instances = kwargs.pop('instances', None)
|
instances = kwargs.pop("instances", None)
|
||||||
super(DelServiceForm, self).__init__(*args, **kwargs)
|
super(DelServiceForm, self).__init__(*args, **kwargs)
|
||||||
if instances:
|
if instances:
|
||||||
self.fields['service'].queryset = instances
|
self.fields["service"].queryset = instances
|
||||||
else:
|
else:
|
||||||
self.fields['service'].queryset = Service.objects.all()
|
self.fields["service"].queryset = Service.objects.all()
|
||||||
|
|
||||||
|
|
||||||
class VlanForm(FormRevMixin, ModelForm):
|
class VlanForm(FormRevMixin, ModelForm):
|
||||||
|
@ -597,39 +616,41 @@ class VlanForm(FormRevMixin, ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Vlan
|
model = Vlan
|
||||||
fields = ['vlan_id', 'name', 'comment']
|
fields = ["vlan_id", "name", "comment"]
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
super(VlanForm, self).__init__(*args, prefix=prefix, **kwargs)
|
super(VlanForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class EditOptionVlanForm(FormRevMixin, ModelForm):
|
class EditOptionVlanForm(FormRevMixin, ModelForm):
|
||||||
"""Ajout d'un vlan : id, nom"""
|
"""Ajout d'un vlan : id, nom"""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Vlan
|
model = Vlan
|
||||||
fields = ['dhcp_snooping', 'dhcpv6_snooping', 'arp_protect', 'igmp', 'mld']
|
fields = ["dhcp_snooping", "dhcpv6_snooping", "arp_protect", "igmp", "mld"]
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
super(EditOptionVlanForm, self).__init__(*args, prefix=prefix, **kwargs)
|
super(EditOptionVlanForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class DelVlanForm(FormRevMixin, Form):
|
class DelVlanForm(FormRevMixin, Form):
|
||||||
"""Suppression d'un ou plusieurs vlans"""
|
"""Suppression d'un ou plusieurs vlans"""
|
||||||
|
|
||||||
vlan = forms.ModelMultipleChoiceField(
|
vlan = forms.ModelMultipleChoiceField(
|
||||||
queryset=Vlan.objects.none(),
|
queryset=Vlan.objects.none(),
|
||||||
label=_("Current VLANs"),
|
label=_("Current VLANs"),
|
||||||
widget=forms.CheckboxSelectMultiple
|
widget=forms.CheckboxSelectMultiple,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
instances = kwargs.pop('instances', None)
|
instances = kwargs.pop("instances", None)
|
||||||
super(DelVlanForm, self).__init__(*args, **kwargs)
|
super(DelVlanForm, self).__init__(*args, **kwargs)
|
||||||
if instances:
|
if instances:
|
||||||
self.fields['vlan'].queryset = instances
|
self.fields["vlan"].queryset = instances
|
||||||
else:
|
else:
|
||||||
self.fields['vlan'].queryset = Vlan.objects.all()
|
self.fields["vlan"].queryset = Vlan.objects.all()
|
||||||
|
|
||||||
|
|
||||||
class EditOuverturePortConfigForm(FormRevMixin, ModelForm):
|
class EditOuverturePortConfigForm(FormRevMixin, ModelForm):
|
||||||
|
@ -638,14 +659,12 @@ class EditOuverturePortConfigForm(FormRevMixin, ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Interface
|
model = Interface
|
||||||
fields = ['port_lists']
|
fields = ["port_lists"]
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
super(EditOuverturePortConfigForm, self).__init__(
|
super(EditOuverturePortConfigForm, self).__init__(
|
||||||
*args,
|
*args, prefix=prefix, **kwargs
|
||||||
prefix=prefix,
|
|
||||||
**kwargs
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -655,15 +674,11 @@ class EditOuverturePortListForm(FormRevMixin, ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = OuverturePortList
|
model = OuverturePortList
|
||||||
fields = '__all__'
|
fields = "__all__"
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
super(EditOuverturePortListForm, self).__init__(
|
super(EditOuverturePortListForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
*args,
|
|
||||||
prefix=prefix,
|
|
||||||
**kwargs
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class SshFpForm(FormRevMixin, ModelForm):
|
class SshFpForm(FormRevMixin, ModelForm):
|
||||||
|
@ -671,12 +686,8 @@ class SshFpForm(FormRevMixin, ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SshFp
|
model = SshFp
|
||||||
exclude = ('machine',)
|
exclude = ("machine",)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
super(SshFpForm, self).__init__(
|
super(SshFpForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
*args,
|
|
||||||
prefix=prefix,
|
|
||||||
**kwargs
|
|
||||||
)
|
|
||||||
|
|
|
@ -29,32 +29,50 @@ import django.db.models.deletion
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("users", "0005_auto_20160702_0006")]
|
||||||
('users', '0005_auto_20160702_0006'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Machine',
|
name="Machine",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
(
|
||||||
|
"id",
|
||||||
|
models.AutoField(
|
||||||
|
verbose_name="ID",
|
||||||
|
serialize=False,
|
||||||
|
auto_created=True,
|
||||||
|
primary_key=True,
|
||||||
|
),
|
||||||
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='MachineType',
|
name="MachineType",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
(
|
||||||
('type', models.CharField(max_length=255)),
|
"id",
|
||||||
|
models.AutoField(
|
||||||
|
verbose_name="ID",
|
||||||
|
serialize=False,
|
||||||
|
auto_created=True,
|
||||||
|
primary_key=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("type", models.CharField(max_length=255)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='machine',
|
model_name="machine",
|
||||||
name='type',
|
name="type",
|
||||||
field=models.ForeignKey(to='machines.MachineType', on_delete=django.db.models.deletion.PROTECT),
|
field=models.ForeignKey(
|
||||||
|
to="machines.MachineType", on_delete=django.db.models.deletion.PROTECT
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='machine',
|
model_name="machine",
|
||||||
name='user',
|
name="user",
|
||||||
field=models.ForeignKey(to='users.User', on_delete=django.db.models.deletion.PROTECT),
|
field=models.ForeignKey(
|
||||||
|
to="users.User", on_delete=django.db.models.deletion.PROTECT
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -30,36 +30,57 @@ import macaddress.fields
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("machines", "0001_initial")]
|
||||||
('machines', '0001_initial'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Interface',
|
name="Interface",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(serialize=False, verbose_name='ID', auto_created=True, primary_key=True)),
|
(
|
||||||
('ipv6', models.GenericIPAddressField(protocol='IPv6')),
|
"id",
|
||||||
('mac_address', macaddress.fields.MACAddressField(integer=True)),
|
models.AutoField(
|
||||||
('details', models.CharField(max_length=255)),
|
serialize=False,
|
||||||
('name', models.CharField(max_length=255, blank=True, unique=True)),
|
verbose_name="ID",
|
||||||
|
auto_created=True,
|
||||||
|
primary_key=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("ipv6", models.GenericIPAddressField(protocol="IPv6")),
|
||||||
|
("mac_address", macaddress.fields.MACAddressField(integer=True)),
|
||||||
|
("details", models.CharField(max_length=255)),
|
||||||
|
("name", models.CharField(max_length=255, blank=True, unique=True)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='IpList',
|
name="IpList",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(serialize=False, verbose_name='ID', auto_created=True, primary_key=True)),
|
(
|
||||||
('ipv4', models.GenericIPAddressField(protocol='IPv4')),
|
"id",
|
||||||
|
models.AutoField(
|
||||||
|
serialize=False,
|
||||||
|
verbose_name="ID",
|
||||||
|
auto_created=True,
|
||||||
|
primary_key=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("ipv4", models.GenericIPAddressField(protocol="IPv4")),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='interface',
|
model_name="interface",
|
||||||
name='ipv4',
|
name="ipv4",
|
||||||
field=models.OneToOneField(null=True, to='machines.IpList', blank=True, on_delete=django.db.models.deletion.PROTECT),
|
field=models.OneToOneField(
|
||||||
|
null=True,
|
||||||
|
to="machines.IpList",
|
||||||
|
blank=True,
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='interface',
|
model_name="interface",
|
||||||
name='machine',
|
name="machine",
|
||||||
field=models.ForeignKey(to='machines.Machine', on_delete=django.db.models.deletion.PROTECT),
|
field=models.ForeignKey(
|
||||||
|
to="machines.Machine", on_delete=django.db.models.deletion.PROTECT
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -29,14 +29,12 @@ import macaddress.fields
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("machines", "0002_auto_20160703_1444")]
|
||||||
('machines', '0002_auto_20160703_1444'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='interface',
|
model_name="interface",
|
||||||
name='mac_address',
|
name="mac_address",
|
||||||
field=macaddress.fields.MACAddressField(integer=True, unique=True),
|
field=macaddress.fields.MACAddressField(integer=True, unique=True),
|
||||||
),
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -28,14 +28,12 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("machines", "0003_auto_20160703_1450")]
|
||||||
('machines', '0003_auto_20160703_1450'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='iplist',
|
model_name="iplist",
|
||||||
name='ipv4',
|
name="ipv4",
|
||||||
field=models.GenericIPAddressField(protocol='IPv4', unique=True),
|
field=models.GenericIPAddressField(protocol="IPv4", unique=True),
|
||||||
),
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -28,19 +28,15 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("machines", "0004_auto_20160703_1451")]
|
||||||
('machines', '0004_auto_20160703_1451'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.RenameField(
|
migrations.RenameField(model_name="interface", old_name="name", new_name="dns"),
|
||||||
model_name='interface',
|
|
||||||
old_name='name',
|
|
||||||
new_name='dns',
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='machine',
|
model_name="machine",
|
||||||
name='name',
|
name="name",
|
||||||
field=models.CharField(blank=True, unique=True, max_length=255, help_text='Optionnel'),
|
field=models.CharField(
|
||||||
|
blank=True, unique=True, max_length=255, help_text="Optionnel"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue