mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-12-28 09:53:47 +00:00
parent
2460a7d2a0
commit
c4a104b3b6
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(
|
||||
app_label=settings.API_CONTENT_TYPE_APP_LABEL,
|
||||
model=settings.API_CONTENT_TYPE_MODEL
|
||||
model=settings.API_CONTENT_TYPE_MODEL,
|
||||
)
|
||||
if created:
|
||||
api_content_type.save()
|
||||
api_permission, created = Permission.objects.get_or_create(
|
||||
name=settings.API_PERMISSION_NAME,
|
||||
content_type=api_content_type,
|
||||
codename=settings.API_PERMISSION_CODENAME
|
||||
codename=settings.API_PERMISSION_CODENAME,
|
||||
)
|
||||
if created:
|
||||
api_permission.save()
|
||||
|
@ -67,10 +67,13 @@ def can_view(user):
|
|||
viewing is granted and msg is a message (can be None).
|
||||
"""
|
||||
kwargs = {
|
||||
'app_label': settings.API_CONTENT_TYPE_APP_LABEL,
|
||||
'codename': settings.API_PERMISSION_CODENAME
|
||||
"app_label": settings.API_CONTENT_TYPE_APP_LABEL,
|
||||
"codename": settings.API_PERMISSION_CODENAME,
|
||||
}
|
||||
permission = '%(app_label)s.%(codename)s' % kwargs
|
||||
permission = "%(app_label)s.%(codename)s" % kwargs
|
||||
can = user.has_perm(permission)
|
||||
return can, None if can else _("You don't have the right to see this"
|
||||
" application."), (permission,)
|
||||
return (
|
||||
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)
|
||||
|
||||
# Check that the genration time of the token is not too old
|
||||
token_duration = datetime.timedelta(
|
||||
seconds=settings.API_TOKEN_DURATION
|
||||
)
|
||||
token_duration = datetime.timedelta(seconds=settings.API_TOKEN_DURATION)
|
||||
utc_now = datetime.datetime.now(datetime.timezone.utc)
|
||||
if token.created < utc_now - token_duration:
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
defined in the view.
|
||||
"""
|
||||
assert hasattr(view, 'get_' + param_name) \
|
||||
or getattr(view, param_name, None) is not None, (
|
||||
'cannot apply {} on a view that does not set '
|
||||
'`.{}` or have a `.get_{}()` method.'
|
||||
).format(self.__class__.__name__, param_name, param_name)
|
||||
assert (
|
||||
hasattr(view, "get_" + param_name)
|
||||
or getattr(view, param_name, None) is not None
|
||||
), (
|
||||
"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):
|
||||
param = getattr(view, 'get_' + param_name)()
|
||||
assert param is not None, (
|
||||
'{}.get_{}() returned None'
|
||||
).format(view.__class__.__name__, param_name)
|
||||
if hasattr(view, "get_" + param_name):
|
||||
param = getattr(view, "get_" + param_name)()
|
||||
assert param is not None, ("{}.get_{}() returned None").format(
|
||||
view.__class__.__name__, param_name
|
||||
)
|
||||
return param
|
||||
return getattr(view, param_name)
|
||||
|
||||
|
@ -97,7 +101,7 @@ class ACLPermission(permissions.BasePermission):
|
|||
rest_framework.exception.MethodNotAllowed: The requested method
|
||||
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:
|
||||
raise exceptions.MethodNotAllowed(method)
|
||||
|
@ -123,7 +127,7 @@ class ACLPermission(permissions.BasePermission):
|
|||
"""
|
||||
# Workaround to ensure ACLPermissions are not applied
|
||||
# to the root view when using DefaultRouter.
|
||||
if getattr(view, '_ignore_model_permissions', False):
|
||||
if getattr(view, "_ignore_model_permissions", False):
|
||||
return True
|
||||
|
||||
if not request.user or not request.user.is_authenticated:
|
||||
|
@ -148,22 +152,22 @@ class AutodetectACLPermission(permissions.BasePermission):
|
|||
"""
|
||||
|
||||
perms_map = {
|
||||
'GET': [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],
|
||||
'POST': [can_see_api, lambda model: model.can_create],
|
||||
'PUT': [], # No restrictions, apply to objects
|
||||
'PATCH': [], # No restrictions, apply to objects
|
||||
'DELETE': [], # No restrictions, apply to objects
|
||||
"GET": [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],
|
||||
"POST": [can_see_api, lambda model: model.can_create],
|
||||
"PUT": [], # No restrictions, apply to objects
|
||||
"PATCH": [], # No restrictions, apply to objects
|
||||
"DELETE": [], # No restrictions, apply to objects
|
||||
}
|
||||
perms_obj_map = {
|
||||
'GET': [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],
|
||||
'POST': [], # No restrictions, apply to models
|
||||
'PUT': [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],
|
||||
"GET": [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],
|
||||
"POST": [], # No restrictions, apply to models
|
||||
"PUT": [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],
|
||||
}
|
||||
|
||||
def get_required_permissions(self, method, model):
|
||||
|
@ -210,7 +214,7 @@ class AutodetectACLPermission(permissions.BasePermission):
|
|||
|
||||
@staticmethod
|
||||
def _queryset(view):
|
||||
return _get_param_in_view(view, 'queryset')
|
||||
return _get_param_in_view(view, "queryset")
|
||||
|
||||
def has_permission(self, request, view):
|
||||
"""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
|
||||
# to the root view when using DefaultRouter.
|
||||
if getattr(view, '_ignore_model_permissions', False):
|
||||
if getattr(view, "_ignore_model_permissions", False):
|
||||
return True
|
||||
|
||||
if not request.user or not request.user.is_authenticated:
|
||||
|
@ -274,7 +278,7 @@ class AutodetectACLPermission(permissions.BasePermission):
|
|||
# to make another lookup.
|
||||
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]:
|
||||
raise Http404
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ class AllViewsRouter(DefaultRouter):
|
|||
Returns:
|
||||
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):
|
||||
"""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:
|
||||
view_renderers += list(self.schema_renderers)
|
||||
schema_generator = SchemaGenerator(
|
||||
title=self.schema_title,
|
||||
patterns=schema_urls
|
||||
title=self.schema_title, patterns=schema_urls
|
||||
)
|
||||
schema_media_types = [
|
||||
renderer.media_type
|
||||
for renderer in self.schema_renderers
|
||||
renderer.media_type for renderer in self.schema_renderers
|
||||
]
|
||||
|
||||
class APIRoot(views.APIView):
|
||||
|
@ -128,14 +126,14 @@ class AllViewsRouter(DefaultRouter):
|
|||
namespace = request.resolver_match.namespace
|
||||
for key, url_name in api_root_dict.items():
|
||||
if namespace:
|
||||
url_name = namespace + ':' + url_name
|
||||
url_name = namespace + ":" + url_name
|
||||
try:
|
||||
ret[key] = reverse(
|
||||
url_name,
|
||||
args=args,
|
||||
kwargs=kwargs,
|
||||
request=request,
|
||||
format=kwargs.get('format', None)
|
||||
format=kwargs.get("format", None),
|
||||
)
|
||||
except NoReverseMatch:
|
||||
# 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
|
||||
REST_FRAMEWORK = {
|
||||
'URL_FIELD_NAME': 'api_url',
|
||||
'DEFAULT_AUTHENTICATION_CLASSES': (
|
||||
'api.authentication.ExpiringTokenAuthentication',
|
||||
'rest_framework.authentication.SessionAuthentication',
|
||||
"URL_FIELD_NAME": "api_url",
|
||||
"DEFAULT_AUTHENTICATION_CLASSES": (
|
||||
"api.authentication.ExpiringTokenAuthentication",
|
||||
"rest_framework.authentication.SessionAuthentication",
|
||||
),
|
||||
'DEFAULT_PERMISSION_CLASSES': (
|
||||
'api.permissions.AutodetectACLPermission',
|
||||
),
|
||||
'DEFAULT_PAGINATION_CLASS': 'api.pagination.PageSizedPagination',
|
||||
'PAGE_SIZE': 100
|
||||
"DEFAULT_PERMISSION_CLASSES": ("api.permissions.AutodetectACLPermission",),
|
||||
"DEFAULT_PAGINATION_CLASS": "api.pagination.PageSizedPagination",
|
||||
"PAGE_SIZE": 100,
|
||||
}
|
||||
|
||||
# API permission settings
|
||||
API_CONTENT_TYPE_APP_LABEL = 'api'
|
||||
API_CONTENT_TYPE_MODEL = 'api'
|
||||
API_PERMISSION_NAME = 'Can use the API'
|
||||
API_PERMISSION_CODENAME = 'use_api'
|
||||
API_CONTENT_TYPE_APP_LABEL = "api"
|
||||
API_CONTENT_TYPE_MODEL = "api"
|
||||
API_PERMISSION_NAME = "Can use the API"
|
||||
API_PERMISSION_CODENAME = "use_api"
|
||||
|
||||
# Activate token authentication
|
||||
API_APPS = (
|
||||
'rest_framework.authtoken',
|
||||
)
|
||||
API_APPS = ("rest_framework.authtoken",)
|
||||
|
||||
# The expiration time for an authentication token
|
||||
API_TOKEN_DURATION = 86400 # 24 hours
|
||||
|
|
525
api/tests.py
525
api/tests.py
|
@ -50,171 +50,170 @@ class APIEndpointsTestCase(APITestCase):
|
|||
superuser: A superuser (with all permissions) used for the tests and
|
||||
initialized at the beggining of this test case.
|
||||
"""
|
||||
no_auth_endpoints = [
|
||||
'/api/'
|
||||
]
|
||||
|
||||
no_auth_endpoints = ["/api/"]
|
||||
auth_no_perm_endpoints = []
|
||||
auth_perm_endpoints = [
|
||||
'/api/cotisations/article/',
|
||||
'/api/cotisations/article/1/',
|
||||
'/api/cotisations/banque/',
|
||||
'/api/cotisations/banque/1/',
|
||||
'/api/cotisations/cotisation/',
|
||||
'/api/cotisations/cotisation/1/',
|
||||
'/api/cotisations/facture/',
|
||||
'/api/cotisations/facture/1/',
|
||||
'/api/cotisations/paiement/',
|
||||
'/api/cotisations/paiement/1/',
|
||||
'/api/cotisations/vente/',
|
||||
'/api/cotisations/vente/1/',
|
||||
'/api/machines/domain/',
|
||||
'/api/machines/domain/1/',
|
||||
'/api/machines/extension/',
|
||||
'/api/machines/extension/1/',
|
||||
'/api/machines/interface/',
|
||||
'/api/machines/interface/1/',
|
||||
'/api/machines/iplist/',
|
||||
'/api/machines/iplist/1/',
|
||||
'/api/machines/iptype/',
|
||||
'/api/machines/iptype/1/',
|
||||
'/api/machines/ipv6list/',
|
||||
'/api/machines/ipv6list/1/',
|
||||
'/api/machines/machine/',
|
||||
'/api/machines/machine/1/',
|
||||
'/api/machines/machinetype/',
|
||||
'/api/machines/machinetype/1/',
|
||||
'/api/machines/mx/',
|
||||
'/api/machines/mx/1/',
|
||||
'/api/machines/nas/',
|
||||
'/api/machines/nas/1/',
|
||||
'/api/machines/ns/',
|
||||
'/api/machines/ns/1/',
|
||||
'/api/machines/ouvertureportlist/',
|
||||
'/api/machines/ouvertureportlist/1/',
|
||||
'/api/machines/ouvertureport/',
|
||||
'/api/machines/ouvertureport/1/',
|
||||
'/api/machines/servicelink/',
|
||||
'/api/machines/servicelink/1/',
|
||||
'/api/machines/service/',
|
||||
'/api/machines/service/1/',
|
||||
'/api/machines/soa/',
|
||||
'/api/machines/soa/1/',
|
||||
'/api/machines/srv/',
|
||||
'/api/machines/srv/1/',
|
||||
'/api/machines/txt/',
|
||||
'/api/machines/txt/1/',
|
||||
'/api/machines/vlan/',
|
||||
'/api/machines/vlan/1/',
|
||||
'/api/preferences/optionaluser/',
|
||||
'/api/preferences/optionalmachine/',
|
||||
'/api/preferences/optionaltopologie/',
|
||||
'/api/preferences/generaloption/',
|
||||
'/api/preferences/service/',
|
||||
'/api/preferences/service/1/',
|
||||
'/api/preferences/assooption/',
|
||||
'/api/preferences/homeoption/',
|
||||
'/api/preferences/mailmessageoption/',
|
||||
'/api/topologie/acesspoint/',
|
||||
"/api/cotisations/article/",
|
||||
"/api/cotisations/article/1/",
|
||||
"/api/cotisations/banque/",
|
||||
"/api/cotisations/banque/1/",
|
||||
"/api/cotisations/cotisation/",
|
||||
"/api/cotisations/cotisation/1/",
|
||||
"/api/cotisations/facture/",
|
||||
"/api/cotisations/facture/1/",
|
||||
"/api/cotisations/paiement/",
|
||||
"/api/cotisations/paiement/1/",
|
||||
"/api/cotisations/vente/",
|
||||
"/api/cotisations/vente/1/",
|
||||
"/api/machines/domain/",
|
||||
"/api/machines/domain/1/",
|
||||
"/api/machines/extension/",
|
||||
"/api/machines/extension/1/",
|
||||
"/api/machines/interface/",
|
||||
"/api/machines/interface/1/",
|
||||
"/api/machines/iplist/",
|
||||
"/api/machines/iplist/1/",
|
||||
"/api/machines/iptype/",
|
||||
"/api/machines/iptype/1/",
|
||||
"/api/machines/ipv6list/",
|
||||
"/api/machines/ipv6list/1/",
|
||||
"/api/machines/machine/",
|
||||
"/api/machines/machine/1/",
|
||||
"/api/machines/machinetype/",
|
||||
"/api/machines/machinetype/1/",
|
||||
"/api/machines/mx/",
|
||||
"/api/machines/mx/1/",
|
||||
"/api/machines/nas/",
|
||||
"/api/machines/nas/1/",
|
||||
"/api/machines/ns/",
|
||||
"/api/machines/ns/1/",
|
||||
"/api/machines/ouvertureportlist/",
|
||||
"/api/machines/ouvertureportlist/1/",
|
||||
"/api/machines/ouvertureport/",
|
||||
"/api/machines/ouvertureport/1/",
|
||||
"/api/machines/servicelink/",
|
||||
"/api/machines/servicelink/1/",
|
||||
"/api/machines/service/",
|
||||
"/api/machines/service/1/",
|
||||
"/api/machines/soa/",
|
||||
"/api/machines/soa/1/",
|
||||
"/api/machines/srv/",
|
||||
"/api/machines/srv/1/",
|
||||
"/api/machines/txt/",
|
||||
"/api/machines/txt/1/",
|
||||
"/api/machines/vlan/",
|
||||
"/api/machines/vlan/1/",
|
||||
"/api/preferences/optionaluser/",
|
||||
"/api/preferences/optionalmachine/",
|
||||
"/api/preferences/optionaltopologie/",
|
||||
"/api/preferences/generaloption/",
|
||||
"/api/preferences/service/",
|
||||
"/api/preferences/service/1/",
|
||||
"/api/preferences/assooption/",
|
||||
"/api/preferences/homeoption/",
|
||||
"/api/preferences/mailmessageoption/",
|
||||
"/api/topologie/acesspoint/",
|
||||
# 2nd machine to be create (machines_machine_1, topologie_accesspoint_1)
|
||||
'/api/topologie/acesspoint/2/',
|
||||
'/api/topologie/building/',
|
||||
'/api/topologie/building/1/',
|
||||
'/api/topologie/constructorswitch/',
|
||||
'/api/topologie/constructorswitch/1/',
|
||||
'/api/topologie/modelswitch/',
|
||||
'/api/topologie/modelswitch/1/',
|
||||
'/api/topologie/room/',
|
||||
'/api/topologie/room/1/',
|
||||
'/api/topologie/server/',
|
||||
"/api/topologie/acesspoint/2/",
|
||||
"/api/topologie/building/",
|
||||
"/api/topologie/building/1/",
|
||||
"/api/topologie/constructorswitch/",
|
||||
"/api/topologie/constructorswitch/1/",
|
||||
"/api/topologie/modelswitch/",
|
||||
"/api/topologie/modelswitch/1/",
|
||||
"/api/topologie/room/",
|
||||
"/api/topologie/room/1/",
|
||||
"/api/topologie/server/",
|
||||
# 3rd machine to be create (machines_machine_1, topologie_accesspoint_1,
|
||||
# topologie_server_1)
|
||||
'/api/topologie/server/3/',
|
||||
'/api/topologie/stack/',
|
||||
'/api/topologie/stack/1/',
|
||||
'/api/topologie/switch/',
|
||||
"/api/topologie/server/3/",
|
||||
"/api/topologie/stack/",
|
||||
"/api/topologie/stack/1/",
|
||||
"/api/topologie/switch/",
|
||||
# 4th machine to be create (machines_machine_1, topologie_accesspoint_1,
|
||||
# topologie_server_1, topologie_switch_1)
|
||||
'/api/topologie/switch/4/',
|
||||
'/api/topologie/switchbay/',
|
||||
'/api/topologie/switchbay/1/',
|
||||
'/api/topologie/switchport/',
|
||||
'/api/topologie/switchport/1/',
|
||||
'/api/topologie/switchport/2/',
|
||||
'/api/topologie/switchport/3/',
|
||||
'/api/users/adherent/',
|
||||
"/api/topologie/switch/4/",
|
||||
"/api/topologie/switchbay/",
|
||||
"/api/topologie/switchbay/1/",
|
||||
"/api/topologie/switchport/",
|
||||
"/api/topologie/switchport/1/",
|
||||
"/api/topologie/switchport/2/",
|
||||
"/api/topologie/switchport/3/",
|
||||
"/api/users/adherent/",
|
||||
# 3rd user to be create (stduser, superuser, users_adherent_1)
|
||||
'/api/users/adherent/3/',
|
||||
'/api/users/ban/',
|
||||
'/api/users/ban/1/',
|
||||
'/api/users/club/',
|
||||
"/api/users/adherent/3/",
|
||||
"/api/users/ban/",
|
||||
"/api/users/ban/1/",
|
||||
"/api/users/club/",
|
||||
# 4th user to be create (stduser, superuser, users_adherent_1,
|
||||
# users_club_1)
|
||||
'/api/users/club/4/',
|
||||
'/api/users/listright/',
|
||||
"/api/users/club/4/",
|
||||
"/api/users/listright/",
|
||||
# TODO: Merge !145
|
||||
# '/api/users/listright/1/',
|
||||
'/api/users/school/',
|
||||
'/api/users/school/1/',
|
||||
'/api/users/serviceuser/',
|
||||
'/api/users/serviceuser/1/',
|
||||
'/api/users/shell/',
|
||||
'/api/users/shell/1/',
|
||||
'/api/users/user/',
|
||||
'/api/users/user/1/',
|
||||
'/api/users/whitelist/',
|
||||
'/api/users/whitelist/1/',
|
||||
'/api/dns/zones/',
|
||||
'/api/dhcp/hostmacip/',
|
||||
'/api/mailing/standard',
|
||||
'/api/mailing/club',
|
||||
'/api/services/regen/',
|
||||
"/api/users/school/",
|
||||
"/api/users/school/1/",
|
||||
"/api/users/serviceuser/",
|
||||
"/api/users/serviceuser/1/",
|
||||
"/api/users/shell/",
|
||||
"/api/users/shell/1/",
|
||||
"/api/users/user/",
|
||||
"/api/users/user/1/",
|
||||
"/api/users/whitelist/",
|
||||
"/api/users/whitelist/1/",
|
||||
"/api/dns/zones/",
|
||||
"/api/dhcp/hostmacip/",
|
||||
"/api/mailing/standard",
|
||||
"/api/mailing/club",
|
||||
"/api/services/regen/",
|
||||
]
|
||||
not_found_endpoints = [
|
||||
'/api/cotisations/article/4242/',
|
||||
'/api/cotisations/banque/4242/',
|
||||
'/api/cotisations/cotisation/4242/',
|
||||
'/api/cotisations/facture/4242/',
|
||||
'/api/cotisations/paiement/4242/',
|
||||
'/api/cotisations/vente/4242/',
|
||||
'/api/machines/domain/4242/',
|
||||
'/api/machines/extension/4242/',
|
||||
'/api/machines/interface/4242/',
|
||||
'/api/machines/iplist/4242/',
|
||||
'/api/machines/iptype/4242/',
|
||||
'/api/machines/ipv6list/4242/',
|
||||
'/api/machines/machine/4242/',
|
||||
'/api/machines/machinetype/4242/',
|
||||
'/api/machines/mx/4242/',
|
||||
'/api/machines/nas/4242/',
|
||||
'/api/machines/ns/4242/',
|
||||
'/api/machines/ouvertureportlist/4242/',
|
||||
'/api/machines/ouvertureport/4242/',
|
||||
'/api/machines/servicelink/4242/',
|
||||
'/api/machines/service/4242/',
|
||||
'/api/machines/soa/4242/',
|
||||
'/api/machines/srv/4242/',
|
||||
'/api/machines/txt/4242/',
|
||||
'/api/machines/vlan/4242/',
|
||||
'/api/preferences/service/4242/',
|
||||
'/api/topologie/acesspoint/4242/',
|
||||
'/api/topologie/building/4242/',
|
||||
'/api/topologie/constructorswitch/4242/',
|
||||
'/api/topologie/modelswitch/4242/',
|
||||
'/api/topologie/room/4242/',
|
||||
'/api/topologie/server/4242/',
|
||||
'/api/topologie/stack/4242/',
|
||||
'/api/topologie/switch/4242/',
|
||||
'/api/topologie/switchbay/4242/',
|
||||
'/api/topologie/switchport/4242/',
|
||||
'/api/users/adherent/4242/',
|
||||
'/api/users/ban/4242/',
|
||||
'/api/users/club/4242/',
|
||||
'/api/users/listright/4242/',
|
||||
'/api/users/school/4242/',
|
||||
'/api/users/serviceuser/4242/',
|
||||
'/api/users/shell/4242/',
|
||||
'/api/users/user/4242/',
|
||||
'/api/users/whitelist/4242/',
|
||||
"/api/cotisations/article/4242/",
|
||||
"/api/cotisations/banque/4242/",
|
||||
"/api/cotisations/cotisation/4242/",
|
||||
"/api/cotisations/facture/4242/",
|
||||
"/api/cotisations/paiement/4242/",
|
||||
"/api/cotisations/vente/4242/",
|
||||
"/api/machines/domain/4242/",
|
||||
"/api/machines/extension/4242/",
|
||||
"/api/machines/interface/4242/",
|
||||
"/api/machines/iplist/4242/",
|
||||
"/api/machines/iptype/4242/",
|
||||
"/api/machines/ipv6list/4242/",
|
||||
"/api/machines/machine/4242/",
|
||||
"/api/machines/machinetype/4242/",
|
||||
"/api/machines/mx/4242/",
|
||||
"/api/machines/nas/4242/",
|
||||
"/api/machines/ns/4242/",
|
||||
"/api/machines/ouvertureportlist/4242/",
|
||||
"/api/machines/ouvertureport/4242/",
|
||||
"/api/machines/servicelink/4242/",
|
||||
"/api/machines/service/4242/",
|
||||
"/api/machines/soa/4242/",
|
||||
"/api/machines/srv/4242/",
|
||||
"/api/machines/txt/4242/",
|
||||
"/api/machines/vlan/4242/",
|
||||
"/api/preferences/service/4242/",
|
||||
"/api/topologie/acesspoint/4242/",
|
||||
"/api/topologie/building/4242/",
|
||||
"/api/topologie/constructorswitch/4242/",
|
||||
"/api/topologie/modelswitch/4242/",
|
||||
"/api/topologie/room/4242/",
|
||||
"/api/topologie/server/4242/",
|
||||
"/api/topologie/stack/4242/",
|
||||
"/api/topologie/switch/4242/",
|
||||
"/api/topologie/switchbay/4242/",
|
||||
"/api/topologie/switchport/4242/",
|
||||
"/api/users/adherent/4242/",
|
||||
"/api/users/ban/4242/",
|
||||
"/api/users/club/4242/",
|
||||
"/api/users/listright/4242/",
|
||||
"/api/users/school/4242/",
|
||||
"/api/users/serviceuser/4242/",
|
||||
"/api/users/shell/4242/",
|
||||
"/api/users/user/4242/",
|
||||
"/api/users/whitelist/4242/",
|
||||
]
|
||||
|
||||
stduser = None
|
||||
|
@ -232,26 +231,18 @@ class APIEndpointsTestCase(APITestCase):
|
|||
|
||||
# A user with no rights
|
||||
cls.stduser = users.User.objects.create_user(
|
||||
"apistduser",
|
||||
"apistduser",
|
||||
"apistduser@example.net",
|
||||
"apistduser"
|
||||
"apistduser", "apistduser", "apistduser@example.net", "apistduser"
|
||||
)
|
||||
# A user with all the rights
|
||||
cls.superuser = users.User.objects.create_superuser(
|
||||
"apisuperuser",
|
||||
"apisuperuser",
|
||||
"apisuperuser@example.net",
|
||||
"apisuperuser"
|
||||
"apisuperuser", "apisuperuser", "apisuperuser@example.net", "apisuperuser"
|
||||
)
|
||||
|
||||
# Creates 1 instance for each object so the "details" endpoints
|
||||
# can be tested too. Objects need to be created in the right order.
|
||||
# Dependencies (relatedFields, ...) are highlighted by a comment at
|
||||
# the end of the concerned line (# Dep <model>).
|
||||
cls.users_school_1 = users.School.objects.create(
|
||||
name="users_school_1"
|
||||
)
|
||||
cls.users_school_1 = users.School.objects.create(name="users_school_1")
|
||||
cls.users_school_1.save()
|
||||
cls.users_listshell_1 = users.ListShell.objects.create(
|
||||
shell="users_listshell_1"
|
||||
|
@ -270,7 +261,7 @@ class APIEndpointsTestCase(APITestCase):
|
|||
registered=datetime.datetime.now(datetime.timezone.utc),
|
||||
telephone="0123456789",
|
||||
uid_number=21102,
|
||||
rezo_rez_uid=21102
|
||||
rezo_rez_uid=21102,
|
||||
)
|
||||
cls.users_user_1 = cls.users_adherent_1
|
||||
cls.cotisations_article_1 = cotisations.Article.objects.create(
|
||||
|
@ -278,14 +269,14 @@ class APIEndpointsTestCase(APITestCase):
|
|||
prix=10,
|
||||
duration=1,
|
||||
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(
|
||||
name="cotisations_banque_1"
|
||||
)
|
||||
cls.cotisations_paiement_1 = cotisations.Paiement.objects.create(
|
||||
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(
|
||||
user=cls.users_user_1, # Dep users.User
|
||||
|
@ -294,7 +285,7 @@ class APIEndpointsTestCase(APITestCase):
|
|||
cheque="1234567890",
|
||||
date=datetime.datetime.now(datetime.timezone.utc),
|
||||
valid=True,
|
||||
control=False
|
||||
control=False,
|
||||
)
|
||||
cls.cotisations_vente_1 = cotisations.Vente.objects.create(
|
||||
facture=cls.cotisations_facture_1, # Dep cotisations.Facture
|
||||
|
@ -302,18 +293,18 @@ class APIEndpointsTestCase(APITestCase):
|
|||
name="cotisations_vente_1",
|
||||
prix=10,
|
||||
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
|
||||
# trying to create another cotisation associated with this vente
|
||||
# will fail so we simply retrieve it so it can be used in the tests
|
||||
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(
|
||||
user=cls.users_user_1, # Dep users.User
|
||||
name="machines_machine_1",
|
||||
active=True
|
||||
active=True,
|
||||
)
|
||||
cls.machines_ouvertureportlist_1 = machines.OuverturePortList.objects.create(
|
||||
name="machines_ouvertureportlist_1"
|
||||
|
@ -324,19 +315,17 @@ class APIEndpointsTestCase(APITestCase):
|
|||
refresh=86400,
|
||||
retry=7200,
|
||||
expire=3600000,
|
||||
ttl=172800
|
||||
ttl=172800,
|
||||
)
|
||||
cls.machines_extension_1 = machines.Extension.objects.create(
|
||||
name="machines_extension_1",
|
||||
need_infra=False,
|
||||
# Do not set origin because of circular dependency
|
||||
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(
|
||||
vlan_id=0,
|
||||
name="machines_vlan_1",
|
||||
comment="machines Vlan 1"
|
||||
vlan_id=0, name="machines_vlan_1", comment="machines Vlan 1"
|
||||
)
|
||||
cls.machines_iptype_1 = machines.IpType.objects.create(
|
||||
type="machines_iptype_1",
|
||||
|
@ -346,13 +335,12 @@ class APIEndpointsTestCase(APITestCase):
|
|||
domaine_ip_stop="10.0.0.255",
|
||||
prefix_v6="2001:db8:1234::",
|
||||
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
|
||||
# new ones and thus we only retrieve it if needed in the tests
|
||||
cls.machines_iplist_1 = machines.IpList.objects.get(
|
||||
ipv4="10.0.0.1",
|
||||
ip_type=cls.machines_iptype_1, # Dep machines.IpType
|
||||
ipv4="10.0.0.1", ip_type=cls.machines_iptype_1 # Dep machines.IpType
|
||||
)
|
||||
cls.machines_machinetype_1 = machines.MachineType.objects.create(
|
||||
type="machines_machinetype_1",
|
||||
|
@ -375,16 +363,16 @@ class APIEndpointsTestCase(APITestCase):
|
|||
cls.machines_mx_1 = machines.Mx.objects.create(
|
||||
zone=cls.machines_extension_1, # Dep machines.Extension
|
||||
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(
|
||||
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(
|
||||
zone=cls.machines_extension_1, # Dep machines.Extension
|
||||
field1="machines_txt_1",
|
||||
field2="machies Txt 1"
|
||||
field2="machies Txt 1",
|
||||
)
|
||||
cls.machines_srv_1 = machines.Srv.objects.create(
|
||||
service="machines_srv_1",
|
||||
|
@ -398,7 +386,7 @@ class APIEndpointsTestCase(APITestCase):
|
|||
cls.machines_ipv6list_1 = machines.Ipv6List.objects.create(
|
||||
ipv6="2001:db8:1234::",
|
||||
interface=cls.machines_interface_1, # Dep machines.Interface
|
||||
slaac_ip=False
|
||||
slaac_ip=False,
|
||||
)
|
||||
cls.machines_service_1 = machines.Service.objects.create(
|
||||
service_type="machines_service_1",
|
||||
|
@ -410,45 +398,45 @@ class APIEndpointsTestCase(APITestCase):
|
|||
service=cls.machines_service_1, # Dep machines.Service
|
||||
server=cls.machines_interface_1, # Dep machines.Interface
|
||||
last_regen=datetime.datetime.now(datetime.timezone.utc),
|
||||
asked_regen=False
|
||||
asked_regen=False,
|
||||
)
|
||||
cls.machines_ouvertureport_1 = machines.OuverturePort.objects.create(
|
||||
begin=1,
|
||||
end=2,
|
||||
port_list=cls.machines_ouvertureportlist_1, # Dep machines.OuverturePortList
|
||||
protocole=machines.OuverturePort.TCP,
|
||||
io=machines.OuverturePort.OUT
|
||||
io=machines.OuverturePort.OUT,
|
||||
)
|
||||
cls.machines_nas_1 = machines.Nas.objects.create(
|
||||
name="machines_nas_1",
|
||||
nas_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],
|
||||
autocapture_mac=False
|
||||
autocapture_mac=False,
|
||||
)
|
||||
cls.preferences_service_1 = preferences.Service.objects.create(
|
||||
name="preferences_service_1",
|
||||
url="https://example.net",
|
||||
description="preferences Service 1",
|
||||
image="/media/logo/none.png"
|
||||
image="/media/logo/none.png",
|
||||
)
|
||||
cls.topologie_stack_1 = topologie.Stack.objects.create(
|
||||
name="topologie_stack_1",
|
||||
stack_id="1",
|
||||
details="topologie Stack 1",
|
||||
member_id_min=1,
|
||||
member_id_max=10
|
||||
member_id_max=10,
|
||||
)
|
||||
cls.topologie_accespoint_1 = topologie.AccessPoint.objects.create(
|
||||
user=cls.users_user_1, # Dep users.User
|
||||
name="machines_machine_1",
|
||||
active=True,
|
||||
location="topologie AccessPoint 1"
|
||||
location="topologie AccessPoint 1",
|
||||
)
|
||||
cls.topologie_server_1 = topologie.Server.objects.create(
|
||||
user=cls.users_user_1, # Dep users.User
|
||||
name="machines_machine_1",
|
||||
active=True
|
||||
active=True,
|
||||
)
|
||||
cls.topologie_building_1 = topologie.Building.objects.create(
|
||||
name="topologie_building_1"
|
||||
|
@ -456,14 +444,14 @@ class APIEndpointsTestCase(APITestCase):
|
|||
cls.topologie_switchbay_1 = topologie.SwitchBay.objects.create(
|
||||
name="topologie_switchbay_1",
|
||||
building=cls.topologie_building_1, # Dep topologie.Building
|
||||
info="topologie SwitchBay 1"
|
||||
info="topologie SwitchBay 1",
|
||||
)
|
||||
cls.topologie_constructorswitch_1 = topologie.ConstructorSwitch.objects.create(
|
||||
name="topologie_constructorswitch_1"
|
||||
)
|
||||
cls.topologie_modelswitch_1 = topologie.ModelSwitch.objects.create(
|
||||
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(
|
||||
user=cls.users_user_1, # Dep users.User
|
||||
|
@ -473,11 +461,10 @@ class APIEndpointsTestCase(APITestCase):
|
|||
stack=cls.topologie_stack_1, # Dep topologie.Stack
|
||||
stack_member_id=1,
|
||||
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(
|
||||
name="topologie_romm_1",
|
||||
details="topologie Room 1"
|
||||
name="topologie_romm_1", details="topologie Room 1"
|
||||
)
|
||||
cls.topologie_port_1 = topologie.Port.objects.create(
|
||||
switch=cls.topologie_switch_1, # Dep topologie.Switch
|
||||
|
@ -485,7 +472,7 @@ class APIEndpointsTestCase(APITestCase):
|
|||
room=cls.topologie_room_1, # Dep topologie.Room
|
||||
radius=topologie.Port.STATES[0][0],
|
||||
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(
|
||||
switch=cls.topologie_switch_1, # Dep topologie.Switch
|
||||
|
@ -493,7 +480,7 @@ class APIEndpointsTestCase(APITestCase):
|
|||
machine_interface=cls.machines_interface_1, # Dep machines.Interface
|
||||
radius=topologie.Port.STATES[0][0],
|
||||
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(
|
||||
switch=cls.topologie_switch_1, # Dep topologie.Switch
|
||||
|
@ -501,14 +488,15 @@ class APIEndpointsTestCase(APITestCase):
|
|||
room=cls.topologie_room_1, # Dep topologie.Room
|
||||
radius=topologie.Port.STATES[0][0],
|
||||
# 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(
|
||||
user=cls.users_user_1, # Dep users.User
|
||||
raison="users Ban 1",
|
||||
date_start=datetime.datetime.now(datetime.timezone.utc),
|
||||
date_end=datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(days=1),
|
||||
state=users.Ban.STATES[0][0]
|
||||
date_end=datetime.datetime.now(datetime.timezone.utc)
|
||||
+ datetime.timedelta(days=1),
|
||||
state=users.Ban.STATES[0][0],
|
||||
)
|
||||
cls.users_club_1 = users.Club.objects.create(
|
||||
password="password",
|
||||
|
@ -524,7 +512,7 @@ class APIEndpointsTestCase(APITestCase):
|
|||
registered=datetime.datetime.now(datetime.timezone.utc),
|
||||
telephone="0123456789",
|
||||
uid_number=21103,
|
||||
rezo_rez_uid=21103
|
||||
rezo_rez_uid=21103,
|
||||
)
|
||||
# Need merge of MR145 to work
|
||||
# TODO: Merge !145
|
||||
|
@ -539,17 +527,17 @@ class APIEndpointsTestCase(APITestCase):
|
|||
last_login=datetime.datetime.now(datetime.timezone.utc),
|
||||
pseudo="usersserviceuser1",
|
||||
access_group=users.ServiceUser.ACCESS[0][0],
|
||||
comment="users ServiceUser 1"
|
||||
comment="users ServiceUser 1",
|
||||
)
|
||||
cls.users_whitelist_1 = users.Whitelist.objects.create(
|
||||
user=cls.users_user_1,
|
||||
raison="users Whitelist 1",
|
||||
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,
|
||||
assert_more=None):
|
||||
def check_responses_code(self, urls, expected_code, formats=None, assert_more=None):
|
||||
"""Utility function to test if a list of urls answer an expected code.
|
||||
|
||||
Args:
|
||||
|
@ -665,17 +653,20 @@ class APIEndpointsTestCase(APITestCase):
|
|||
"""
|
||||
self.client.force_authenticate(user=self.superuser)
|
||||
|
||||
urls = self.no_auth_endpoints + self.auth_no_perm_endpoints + \
|
||||
self.auth_perm_endpoints
|
||||
urls = (
|
||||
self.no_auth_endpoints
|
||||
+ self.auth_no_perm_endpoints
|
||||
+ self.auth_perm_endpoints
|
||||
)
|
||||
|
||||
def assert_more(response, url, format):
|
||||
"""Assert the response is valid json when format is json"""
|
||||
if format is 'json':
|
||||
if format is "json":
|
||||
json.loads(response.content.decode())
|
||||
|
||||
self.check_responses_code(urls, codes.ok,
|
||||
formats=[None, 'json', 'api'],
|
||||
assert_more=assert_more)
|
||||
self.check_responses_code(
|
||||
urls, codes.ok, formats=[None, "json", "api"], assert_more=assert_more
|
||||
)
|
||||
|
||||
|
||||
class APIPaginationTestCase(APITestCase):
|
||||
|
@ -688,56 +679,56 @@ class APIPaginationTestCase(APITestCase):
|
|||
"""
|
||||
|
||||
endpoints = [
|
||||
'/api/cotisations/article/',
|
||||
'/api/cotisations/banque/',
|
||||
'/api/cotisations/cotisation/',
|
||||
'/api/cotisations/facture/',
|
||||
'/api/cotisations/paiement/',
|
||||
'/api/cotisations/vente/',
|
||||
'/api/machines/domain/',
|
||||
'/api/machines/extension/',
|
||||
'/api/machines/interface/',
|
||||
'/api/machines/iplist/',
|
||||
'/api/machines/iptype/',
|
||||
'/api/machines/ipv6list/',
|
||||
'/api/machines/machine/',
|
||||
'/api/machines/machinetype/',
|
||||
'/api/machines/mx/',
|
||||
'/api/machines/nas/',
|
||||
'/api/machines/ns/',
|
||||
'/api/machines/ouvertureportlist/',
|
||||
'/api/machines/ouvertureport/',
|
||||
'/api/machines/servicelink/',
|
||||
'/api/machines/service/',
|
||||
'/api/machines/soa/',
|
||||
'/api/machines/srv/',
|
||||
'/api/machines/txt/',
|
||||
'/api/machines/vlan/',
|
||||
'/api/preferences/service/',
|
||||
'/api/topologie/acesspoint/',
|
||||
'/api/topologie/building/',
|
||||
'/api/topologie/constructorswitch/',
|
||||
'/api/topologie/modelswitch/',
|
||||
'/api/topologie/room/',
|
||||
'/api/topologie/server/',
|
||||
'/api/topologie/stack/',
|
||||
'/api/topologie/switch/',
|
||||
'/api/topologie/switchbay/',
|
||||
'/api/topologie/switchport/',
|
||||
'/api/users/adherent/',
|
||||
'/api/users/ban/',
|
||||
'/api/users/club/',
|
||||
'/api/users/listright/',
|
||||
'/api/users/school/',
|
||||
'/api/users/serviceuser/',
|
||||
'/api/users/shell/',
|
||||
'/api/users/user/',
|
||||
'/api/users/whitelist/',
|
||||
'/api/dns/zones/',
|
||||
'/api/dhcp/hostmacip/',
|
||||
'/api/mailing/standard',
|
||||
'/api/mailing/club',
|
||||
'/api/services/regen/',
|
||||
"/api/cotisations/article/",
|
||||
"/api/cotisations/banque/",
|
||||
"/api/cotisations/cotisation/",
|
||||
"/api/cotisations/facture/",
|
||||
"/api/cotisations/paiement/",
|
||||
"/api/cotisations/vente/",
|
||||
"/api/machines/domain/",
|
||||
"/api/machines/extension/",
|
||||
"/api/machines/interface/",
|
||||
"/api/machines/iplist/",
|
||||
"/api/machines/iptype/",
|
||||
"/api/machines/ipv6list/",
|
||||
"/api/machines/machine/",
|
||||
"/api/machines/machinetype/",
|
||||
"/api/machines/mx/",
|
||||
"/api/machines/nas/",
|
||||
"/api/machines/ns/",
|
||||
"/api/machines/ouvertureportlist/",
|
||||
"/api/machines/ouvertureport/",
|
||||
"/api/machines/servicelink/",
|
||||
"/api/machines/service/",
|
||||
"/api/machines/soa/",
|
||||
"/api/machines/srv/",
|
||||
"/api/machines/txt/",
|
||||
"/api/machines/vlan/",
|
||||
"/api/preferences/service/",
|
||||
"/api/topologie/acesspoint/",
|
||||
"/api/topologie/building/",
|
||||
"/api/topologie/constructorswitch/",
|
||||
"/api/topologie/modelswitch/",
|
||||
"/api/topologie/room/",
|
||||
"/api/topologie/server/",
|
||||
"/api/topologie/stack/",
|
||||
"/api/topologie/switch/",
|
||||
"/api/topologie/switchbay/",
|
||||
"/api/topologie/switchport/",
|
||||
"/api/users/adherent/",
|
||||
"/api/users/ban/",
|
||||
"/api/users/club/",
|
||||
"/api/users/listright/",
|
||||
"/api/users/school/",
|
||||
"/api/users/serviceuser/",
|
||||
"/api/users/shell/",
|
||||
"/api/users/user/",
|
||||
"/api/users/whitelist/",
|
||||
"/api/dns/zones/",
|
||||
"/api/dhcp/hostmacip/",
|
||||
"/api/mailing/standard",
|
||||
"/api/mailing/club",
|
||||
"/api/services/regen/",
|
||||
]
|
||||
superuser = None
|
||||
|
||||
|
@ -745,14 +736,14 @@ class APIPaginationTestCase(APITestCase):
|
|||
def setUpTestData(cls):
|
||||
# A user with all the rights
|
||||
# We need to use a different username than for the first
|
||||
# test case because TestCase is using rollbacks which don't
|
||||
# test case because TestCase is using rollbacks which don't
|
||||
# trigger the ldap_sync() thus the LDAP still have data about
|
||||
# the old users.
|
||||
cls.superuser = users.User.objects.create_superuser(
|
||||
"apisuperuser2",
|
||||
"apisuperuser2",
|
||||
"apisuperuser2@example.net",
|
||||
"apisuperuser2"
|
||||
"apisuperuser2",
|
||||
)
|
||||
|
||||
@classmethod
|
||||
|
@ -771,10 +762,10 @@ class APIPaginationTestCase(APITestCase):
|
|||
self.client.force_authenticate(self.superuser)
|
||||
for url in self.endpoints:
|
||||
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())
|
||||
assert 'count' in res_json.keys()
|
||||
assert 'next' in res_json.keys()
|
||||
assert 'previous' in res_json.keys()
|
||||
assert 'results' in res_json.keys()
|
||||
assert not len('results') > 100
|
||||
assert "count" in res_json.keys()
|
||||
assert "next" in res_json.keys()
|
||||
assert "previous" in res_json.keys()
|
||||
assert "results" in res_json.keys()
|
||||
assert not len("results") > 100
|
||||
|
|
170
api/urls.py
170
api/urls.py
|
@ -34,95 +34,109 @@ from .routers import AllViewsRouter
|
|||
|
||||
router = AllViewsRouter()
|
||||
# COTISATIONS
|
||||
router.register_viewset(r'cotisations/facture', views.FactureViewSet)
|
||||
router.register_viewset(r'cotisations/vente', views.VenteViewSet)
|
||||
router.register_viewset(r'cotisations/article', views.ArticleViewSet)
|
||||
router.register_viewset(r'cotisations/banque', views.BanqueViewSet)
|
||||
router.register_viewset(r'cotisations/paiement', views.PaiementViewSet)
|
||||
router.register_viewset(r'cotisations/cotisation', views.CotisationViewSet)
|
||||
router.register_viewset(r"cotisations/facture", views.FactureViewSet)
|
||||
router.register_viewset(r"cotisations/vente", views.VenteViewSet)
|
||||
router.register_viewset(r"cotisations/article", views.ArticleViewSet)
|
||||
router.register_viewset(r"cotisations/banque", views.BanqueViewSet)
|
||||
router.register_viewset(r"cotisations/paiement", views.PaiementViewSet)
|
||||
router.register_viewset(r"cotisations/cotisation", views.CotisationViewSet)
|
||||
# MACHINES
|
||||
router.register_viewset(r'machines/machine', views.MachineViewSet)
|
||||
router.register_viewset(r'machines/machinetype', views.MachineTypeViewSet)
|
||||
router.register_viewset(r'machines/iptype', views.IpTypeViewSet)
|
||||
router.register_viewset(r'machines/vlan', views.VlanViewSet)
|
||||
router.register_viewset(r'machines/nas', views.NasViewSet)
|
||||
router.register_viewset(r'machines/soa', views.SOAViewSet)
|
||||
router.register_viewset(r'machines/extension', views.ExtensionViewSet)
|
||||
router.register_viewset(r'machines/mx', views.MxViewSet)
|
||||
router.register_viewset(r'machines/ns', views.NsViewSet)
|
||||
router.register_viewset(r'machines/txt', views.TxtViewSet)
|
||||
router.register_viewset(r'machines/dname', views.DNameViewSet)
|
||||
router.register_viewset(r'machines/srv', views.SrvViewSet)
|
||||
router.register_viewset(r'machines/sshfp', views.SshFpViewSet)
|
||||
router.register_viewset(r'machines/interface', views.InterfaceViewSet)
|
||||
router.register_viewset(r'machines/ipv6list', views.Ipv6ListViewSet)
|
||||
router.register_viewset(r'machines/domain', views.DomainViewSet)
|
||||
router.register_viewset(r'machines/iplist', views.IpListViewSet)
|
||||
router.register_viewset(r'machines/service', views.ServiceViewSet)
|
||||
router.register_viewset(r'machines/servicelink', views.ServiceLinkViewSet, base_name='servicelink')
|
||||
router.register_viewset(r'machines/ouvertureportlist', views.OuverturePortListViewSet)
|
||||
router.register_viewset(r'machines/ouvertureport', views.OuverturePortViewSet)
|
||||
router.register_viewset(r'machines/role', views.RoleViewSet)
|
||||
router.register_viewset(r"machines/machine", views.MachineViewSet)
|
||||
router.register_viewset(r"machines/machinetype", views.MachineTypeViewSet)
|
||||
router.register_viewset(r"machines/iptype", views.IpTypeViewSet)
|
||||
router.register_viewset(r"machines/vlan", views.VlanViewSet)
|
||||
router.register_viewset(r"machines/nas", views.NasViewSet)
|
||||
router.register_viewset(r"machines/soa", views.SOAViewSet)
|
||||
router.register_viewset(r"machines/extension", views.ExtensionViewSet)
|
||||
router.register_viewset(r"machines/mx", views.MxViewSet)
|
||||
router.register_viewset(r"machines/ns", views.NsViewSet)
|
||||
router.register_viewset(r"machines/txt", views.TxtViewSet)
|
||||
router.register_viewset(r"machines/dname", views.DNameViewSet)
|
||||
router.register_viewset(r"machines/srv", views.SrvViewSet)
|
||||
router.register_viewset(r"machines/sshfp", views.SshFpViewSet)
|
||||
router.register_viewset(r"machines/interface", views.InterfaceViewSet)
|
||||
router.register_viewset(r"machines/ipv6list", views.Ipv6ListViewSet)
|
||||
router.register_viewset(r"machines/domain", views.DomainViewSet)
|
||||
router.register_viewset(r"machines/iplist", views.IpListViewSet)
|
||||
router.register_viewset(r"machines/service", views.ServiceViewSet)
|
||||
router.register_viewset(
|
||||
r"machines/servicelink", views.ServiceLinkViewSet, base_name="servicelink"
|
||||
)
|
||||
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
|
||||
router.register_view(r'preferences/optionaluser', views.OptionalUserView),
|
||||
router.register_view(r'preferences/optionalmachine', views.OptionalMachineView),
|
||||
router.register_view(r'preferences/optionaltopologie', views.OptionalTopologieView),
|
||||
router.register_view(r'preferences/radiusoption', views.RadiusOptionView),
|
||||
router.register_view(r'preferences/generaloption', views.GeneralOptionView),
|
||||
router.register_viewset(r'preferences/service', views.HomeServiceViewSet, base_name='homeservice'),
|
||||
router.register_view(r'preferences/assooption', views.AssoOptionView),
|
||||
router.register_view(r'preferences/homeoption', views.HomeOptionView),
|
||||
router.register_view(r'preferences/mailmessageoption', views.MailMessageOptionView),
|
||||
router.register_view(r"preferences/optionaluser", views.OptionalUserView),
|
||||
router.register_view(r"preferences/optionalmachine", views.OptionalMachineView),
|
||||
router.register_view(r"preferences/optionaltopologie", views.OptionalTopologieView),
|
||||
router.register_view(r"preferences/radiusoption", views.RadiusOptionView),
|
||||
router.register_view(r"preferences/generaloption", views.GeneralOptionView),
|
||||
router.register_viewset(
|
||||
r"preferences/service", views.HomeServiceViewSet, base_name="homeservice"
|
||||
),
|
||||
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
|
||||
router.register_viewset(r'topologie/stack', views.StackViewSet)
|
||||
router.register_viewset(r'topologie/acesspoint', views.AccessPointViewSet)
|
||||
router.register_viewset(r'topologie/switch', views.SwitchViewSet)
|
||||
router.register_viewset(r'topologie/server', views.ServerViewSet)
|
||||
router.register_viewset(r'topologie/modelswitch', views.ModelSwitchViewSet)
|
||||
router.register_viewset(r'topologie/constructorswitch', views.ConstructorSwitchViewSet)
|
||||
router.register_viewset(r'topologie/switchbay', views.SwitchBayViewSet)
|
||||
router.register_viewset(r'topologie/building', views.BuildingViewSet)
|
||||
router.register_viewset(r'topologie/switchport', views.SwitchPortViewSet, base_name='switchport')
|
||||
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)
|
||||
router.register_viewset(r"topologie/stack", views.StackViewSet)
|
||||
router.register_viewset(r"topologie/acesspoint", views.AccessPointViewSet)
|
||||
router.register_viewset(r"topologie/switch", views.SwitchViewSet)
|
||||
router.register_viewset(r"topologie/server", views.ServerViewSet)
|
||||
router.register_viewset(r"topologie/modelswitch", views.ModelSwitchViewSet)
|
||||
router.register_viewset(r"topologie/constructorswitch", views.ConstructorSwitchViewSet)
|
||||
router.register_viewset(r"topologie/switchbay", views.SwitchBayViewSet)
|
||||
router.register_viewset(r"topologie/building", views.BuildingViewSet)
|
||||
router.register_viewset(
|
||||
r"topologie/switchport", views.SwitchPortViewSet, base_name="switchport"
|
||||
)
|
||||
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
|
||||
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(r'users/normaluser', views.NormalUserViewSet, base_name='normaluser')
|
||||
router.register_viewset(r'users/criticaluser', views.CriticalUserViewSet, base_name='criticaluser')
|
||||
router.register_viewset(r'users/club', views.ClubViewSet)
|
||||
router.register_viewset(r'users/adherent', views.AdherentViewSet)
|
||||
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)
|
||||
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(
|
||||
r"users/normaluser", views.NormalUserViewSet, base_name="normaluser"
|
||||
)
|
||||
router.register_viewset(
|
||||
r"users/criticaluser", views.CriticalUserViewSet, base_name="criticaluser"
|
||||
)
|
||||
router.register_viewset(r"users/club", views.ClubViewSet)
|
||||
router.register_viewset(r"users/adherent", views.AdherentViewSet)
|
||||
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
|
||||
router.register_viewset(r'services/regen', views.ServiceRegenViewSet, base_name='serviceregen')
|
||||
router.register_viewset(
|
||||
r"services/regen", views.ServiceRegenViewSet, base_name="serviceregen"
|
||||
)
|
||||
# DHCP
|
||||
router.register_view(r'dhcp/hostmacip', views.HostMacIpView),
|
||||
router.register_view(r"dhcp/hostmacip", views.HostMacIpView),
|
||||
# LOCAL EMAILS
|
||||
router.register_view(r'localemail/users', views.LocalEmailUsersView),
|
||||
router.register_view(r"localemail/users", views.LocalEmailUsersView),
|
||||
# Firewall
|
||||
router.register_view(r'firewall/subnet-ports', views.SubnetPortsOpenView),
|
||||
router.register_view(r'firewall/interface-ports', views.InterfacePortsOpenView),
|
||||
router.register_view(r"firewall/subnet-ports", views.SubnetPortsOpenView),
|
||||
router.register_view(r"firewall/interface-ports", views.InterfacePortsOpenView),
|
||||
# Switches config
|
||||
router.register_view(r'switchs/ports-config', views.SwitchPortView),
|
||||
router.register_view(r'switchs/role', views.RoleView),
|
||||
router.register_view(r"switchs/ports-config", views.SwitchPortView),
|
||||
router.register_view(r"switchs/role", views.RoleView),
|
||||
# Reminder
|
||||
router.register_view(r'reminder/get-users', views.ReminderView),
|
||||
router.register_view(r"reminder/get-users", views.ReminderView),
|
||||
# DNS
|
||||
router.register_view(r'dns/zones', views.DNSZonesView),
|
||||
router.register_view(r'dns/reverse-zones', views.DNSReverseZonesView),
|
||||
router.register_view(r"dns/zones", views.DNSZonesView),
|
||||
router.register_view(r"dns/reverse-zones", views.DNSReverseZonesView),
|
||||
# MAILING
|
||||
router.register_view(r'mailing/standard', views.StandardMailingView),
|
||||
router.register_view(r'mailing/club', views.ClubMailingView),
|
||||
router.register_view(r"mailing/standard", views.StandardMailingView),
|
||||
router.register_view(r"mailing/club", views.ClubMailingView),
|
||||
# TOKEN AUTHENTICATION
|
||||
router.register_view(r'token-auth', views.ObtainExpiringAuthToken)
|
||||
router.register_view(r"token-auth", views.ObtainExpiringAuthToken)
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^', include(router.urls)),
|
||||
]
|
||||
urlpatterns = [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):
|
||||
"""Exposes list and details of `cotisations.models.Facture` objects.
|
||||
"""
|
||||
|
||||
queryset = cotisations.Facture.objects.all()
|
||||
serializer_class = serializers.FactureSerializer
|
||||
|
||||
|
||||
class FactureViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `cotisations.models.Facture` objects.
|
||||
"""
|
||||
|
||||
queryset = cotisations.BaseInvoice.objects.all()
|
||||
serializer_class = serializers.BaseInvoiceSerializer
|
||||
|
||||
|
@ -65,6 +68,7 @@ class FactureViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class VenteViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `cotisations.models.Vente` objects.
|
||||
"""
|
||||
|
||||
queryset = cotisations.Vente.objects.all()
|
||||
serializer_class = serializers.VenteSerializer
|
||||
|
||||
|
@ -72,6 +76,7 @@ class VenteViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class ArticleViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `cotisations.models.Article` objects.
|
||||
"""
|
||||
|
||||
queryset = cotisations.Article.objects.all()
|
||||
serializer_class = serializers.ArticleSerializer
|
||||
|
||||
|
@ -79,6 +84,7 @@ class ArticleViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class BanqueViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `cotisations.models.Banque` objects.
|
||||
"""
|
||||
|
||||
queryset = cotisations.Banque.objects.all()
|
||||
serializer_class = serializers.BanqueSerializer
|
||||
|
||||
|
@ -86,6 +92,7 @@ class BanqueViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class PaiementViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `cotisations.models.Paiement` objects.
|
||||
"""
|
||||
|
||||
queryset = cotisations.Paiement.objects.all()
|
||||
serializer_class = serializers.PaiementSerializer
|
||||
|
||||
|
@ -93,6 +100,7 @@ class PaiementViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class CotisationViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `cotisations.models.Cotisation` objects.
|
||||
"""
|
||||
|
||||
queryset = cotisations.Cotisation.objects.all()
|
||||
serializer_class = serializers.CotisationSerializer
|
||||
|
||||
|
@ -103,6 +111,7 @@ class CotisationViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class MachineViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `machines.models.Machine` objects.
|
||||
"""
|
||||
|
||||
queryset = machines.Machine.objects.all()
|
||||
serializer_class = serializers.MachineSerializer
|
||||
|
||||
|
@ -110,6 +119,7 @@ class MachineViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class MachineTypeViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `machines.models.MachineType` objects.
|
||||
"""
|
||||
|
||||
queryset = machines.MachineType.objects.all()
|
||||
serializer_class = serializers.MachineTypeSerializer
|
||||
|
||||
|
@ -117,6 +127,7 @@ class MachineTypeViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class IpTypeViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `machines.models.IpType` objects.
|
||||
"""
|
||||
|
||||
queryset = machines.IpType.objects.all()
|
||||
serializer_class = serializers.IpTypeSerializer
|
||||
|
||||
|
@ -124,6 +135,7 @@ class IpTypeViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class VlanViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `machines.models.Vlan` objects.
|
||||
"""
|
||||
|
||||
queryset = machines.Vlan.objects.all()
|
||||
serializer_class = serializers.VlanSerializer
|
||||
|
||||
|
@ -131,6 +143,7 @@ class VlanViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class NasViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `machines.models.Nas` objects.
|
||||
"""
|
||||
|
||||
queryset = machines.Nas.objects.all()
|
||||
serializer_class = serializers.NasSerializer
|
||||
|
||||
|
@ -138,6 +151,7 @@ class NasViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class SOAViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `machines.models.SOA` objects.
|
||||
"""
|
||||
|
||||
queryset = machines.SOA.objects.all()
|
||||
serializer_class = serializers.SOASerializer
|
||||
|
||||
|
@ -145,6 +159,7 @@ class SOAViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class ExtensionViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `machines.models.Extension` objects.
|
||||
"""
|
||||
|
||||
queryset = machines.Extension.objects.all()
|
||||
serializer_class = serializers.ExtensionSerializer
|
||||
|
||||
|
@ -152,6 +167,7 @@ class ExtensionViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class MxViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `machines.models.Mx` objects.
|
||||
"""
|
||||
|
||||
queryset = machines.Mx.objects.all()
|
||||
serializer_class = serializers.MxSerializer
|
||||
|
||||
|
@ -159,6 +175,7 @@ class MxViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class NsViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `machines.models.Ns` objects.
|
||||
"""
|
||||
|
||||
queryset = machines.Ns.objects.all()
|
||||
serializer_class = serializers.NsSerializer
|
||||
|
||||
|
@ -166,6 +183,7 @@ class NsViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class TxtViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `machines.models.Txt` objects.
|
||||
"""
|
||||
|
||||
queryset = machines.Txt.objects.all()
|
||||
serializer_class = serializers.TxtSerializer
|
||||
|
||||
|
@ -173,6 +191,7 @@ class TxtViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class DNameViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `machines.models.DName` objects.
|
||||
"""
|
||||
|
||||
queryset = machines.DName.objects.all()
|
||||
serializer_class = serializers.DNameSerializer
|
||||
|
||||
|
@ -180,6 +199,7 @@ class DNameViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class SrvViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `machines.models.Srv` objects.
|
||||
"""
|
||||
|
||||
queryset = machines.Srv.objects.all()
|
||||
serializer_class = serializers.SrvSerializer
|
||||
|
||||
|
@ -187,6 +207,7 @@ class SrvViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class SshFpViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `machines.models.SshFp` objects.
|
||||
"""
|
||||
|
||||
queryset = machines.SshFp.objects.all()
|
||||
serializer_class = serializers.SshFpSerializer
|
||||
|
||||
|
@ -194,6 +215,7 @@ class SshFpViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class InterfaceViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `machines.models.Interface` objects.
|
||||
"""
|
||||
|
||||
queryset = machines.Interface.objects.all()
|
||||
serializer_class = serializers.InterfaceSerializer
|
||||
|
||||
|
@ -201,6 +223,7 @@ class InterfaceViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class Ipv6ListViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `machines.models.Ipv6List` objects.
|
||||
"""
|
||||
|
||||
queryset = machines.Ipv6List.objects.all()
|
||||
serializer_class = serializers.Ipv6ListSerializer
|
||||
|
||||
|
@ -208,6 +231,7 @@ class Ipv6ListViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class DomainViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `machines.models.Domain` objects.
|
||||
"""
|
||||
|
||||
queryset = machines.Domain.objects.all()
|
||||
serializer_class = serializers.DomainSerializer
|
||||
|
||||
|
@ -215,6 +239,7 @@ class DomainViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class IpListViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `machines.models.IpList` objects.
|
||||
"""
|
||||
|
||||
queryset = machines.IpList.objects.all()
|
||||
serializer_class = serializers.IpListSerializer
|
||||
|
||||
|
@ -222,6 +247,7 @@ class IpListViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class ServiceViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `machines.models.Service` objects.
|
||||
"""
|
||||
|
||||
queryset = machines.Service.objects.all()
|
||||
serializer_class = serializers.ServiceSerializer
|
||||
|
||||
|
@ -229,6 +255,7 @@ class ServiceViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class ServiceLinkViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `machines.models.Service_link` objects.
|
||||
"""
|
||||
|
||||
queryset = machines.Service_link.objects.all()
|
||||
serializer_class = serializers.ServiceLinkSerializer
|
||||
|
||||
|
@ -237,6 +264,7 @@ class OuverturePortListViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
"""Exposes list and details of `machines.models.OuverturePortList`
|
||||
objects.
|
||||
"""
|
||||
|
||||
queryset = machines.OuverturePortList.objects.all()
|
||||
serializer_class = serializers.OuverturePortListSerializer
|
||||
|
||||
|
@ -244,6 +272,7 @@ class OuverturePortListViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class OuverturePortViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `machines.models.OuverturePort` objects.
|
||||
"""
|
||||
|
||||
queryset = machines.OuverturePort.objects.all()
|
||||
serializer_class = serializers.OuverturePortSerializer
|
||||
|
||||
|
@ -251,6 +280,7 @@ class OuverturePortViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class RoleViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `machines.models.Machine` objects.
|
||||
"""
|
||||
|
||||
queryset = machines.Role.objects.all()
|
||||
serializer_class = serializers.RoleSerializer
|
||||
|
||||
|
@ -259,11 +289,13 @@ class RoleViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
# Those views differ a bit because there is only one object
|
||||
# to display, so we don't bother with the listing part
|
||||
|
||||
|
||||
class OptionalUserView(generics.RetrieveAPIView):
|
||||
"""Exposes details of `preferences.models.` settings.
|
||||
"""
|
||||
|
||||
permission_classes = (ACLPermission,)
|
||||
perms_map = {'GET': [preferences.OptionalUser.can_view_all]}
|
||||
perms_map = {"GET": [preferences.OptionalUser.can_view_all]}
|
||||
serializer_class = serializers.OptionalUserSerializer
|
||||
|
||||
def get_object(self):
|
||||
|
@ -273,8 +305,9 @@ class OptionalUserView(generics.RetrieveAPIView):
|
|||
class OptionalMachineView(generics.RetrieveAPIView):
|
||||
"""Exposes details of `preferences.models.OptionalMachine` settings.
|
||||
"""
|
||||
|
||||
permission_classes = (ACLPermission,)
|
||||
perms_map = {'GET': [preferences.OptionalMachine.can_view_all]}
|
||||
perms_map = {"GET": [preferences.OptionalMachine.can_view_all]}
|
||||
serializer_class = serializers.OptionalMachineSerializer
|
||||
|
||||
def get_object(self):
|
||||
|
@ -284,8 +317,9 @@ class OptionalMachineView(generics.RetrieveAPIView):
|
|||
class OptionalTopologieView(generics.RetrieveAPIView):
|
||||
"""Exposes details of `preferences.models.OptionalTopologie` settings.
|
||||
"""
|
||||
|
||||
permission_classes = (ACLPermission,)
|
||||
perms_map = {'GET': [preferences.OptionalTopologie.can_view_all]}
|
||||
perms_map = {"GET": [preferences.OptionalTopologie.can_view_all]}
|
||||
serializer_class = serializers.OptionalTopologieSerializer
|
||||
|
||||
def get_object(self):
|
||||
|
@ -295,8 +329,9 @@ class OptionalTopologieView(generics.RetrieveAPIView):
|
|||
class RadiusOptionView(generics.RetrieveAPIView):
|
||||
"""Exposes details of `preferences.models.OptionalTopologie` settings.
|
||||
"""
|
||||
|
||||
permission_classes = (ACLPermission,)
|
||||
perms_map = {'GET': [preferences.RadiusOption.can_view_all]}
|
||||
perms_map = {"GET": [preferences.RadiusOption.can_view_all]}
|
||||
serializer_class = serializers.RadiusOptionSerializer
|
||||
|
||||
def get_object(self):
|
||||
|
@ -306,8 +341,9 @@ class RadiusOptionView(generics.RetrieveAPIView):
|
|||
class GeneralOptionView(generics.RetrieveAPIView):
|
||||
"""Exposes details of `preferences.models.GeneralOption` settings.
|
||||
"""
|
||||
|
||||
permission_classes = (ACLPermission,)
|
||||
perms_map = {'GET': [preferences.GeneralOption.can_view_all]}
|
||||
perms_map = {"GET": [preferences.GeneralOption.can_view_all]}
|
||||
serializer_class = serializers.GeneralOptionSerializer
|
||||
|
||||
def get_object(self):
|
||||
|
@ -317,6 +353,7 @@ class GeneralOptionView(generics.RetrieveAPIView):
|
|||
class HomeServiceViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `preferences.models.Service` objects.
|
||||
"""
|
||||
|
||||
queryset = preferences.Service.objects.all()
|
||||
serializer_class = serializers.HomeServiceSerializer
|
||||
|
||||
|
@ -324,8 +361,9 @@ class HomeServiceViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class AssoOptionView(generics.RetrieveAPIView):
|
||||
"""Exposes details of `preferences.models.AssoOption` settings.
|
||||
"""
|
||||
|
||||
permission_classes = (ACLPermission,)
|
||||
perms_map = {'GET': [preferences.AssoOption.can_view_all]}
|
||||
perms_map = {"GET": [preferences.AssoOption.can_view_all]}
|
||||
serializer_class = serializers.AssoOptionSerializer
|
||||
|
||||
def get_object(self):
|
||||
|
@ -335,8 +373,9 @@ class AssoOptionView(generics.RetrieveAPIView):
|
|||
class HomeOptionView(generics.RetrieveAPIView):
|
||||
"""Exposes details of `preferences.models.HomeOption` settings.
|
||||
"""
|
||||
|
||||
permission_classes = (ACLPermission,)
|
||||
perms_map = {'GET': [preferences.HomeOption.can_view_all]}
|
||||
perms_map = {"GET": [preferences.HomeOption.can_view_all]}
|
||||
serializer_class = serializers.HomeOptionSerializer
|
||||
|
||||
def get_object(self):
|
||||
|
@ -346,8 +385,9 @@ class HomeOptionView(generics.RetrieveAPIView):
|
|||
class MailMessageOptionView(generics.RetrieveAPIView):
|
||||
"""Exposes details of `preferences.models.MailMessageOption` settings.
|
||||
"""
|
||||
|
||||
permission_classes = (ACLPermission,)
|
||||
perms_map = {'GET': [preferences.MailMessageOption.can_view_all]}
|
||||
perms_map = {"GET": [preferences.MailMessageOption.can_view_all]}
|
||||
serializer_class = serializers.MailMessageOptionSerializer
|
||||
|
||||
def get_object(self):
|
||||
|
@ -360,6 +400,7 @@ class MailMessageOptionView(generics.RetrieveAPIView):
|
|||
class StackViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `topologie.models.Stack` objects.
|
||||
"""
|
||||
|
||||
queryset = topologie.Stack.objects.all()
|
||||
serializer_class = serializers.StackSerializer
|
||||
|
||||
|
@ -367,6 +408,7 @@ class StackViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class AccessPointViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `topologie.models.AccessPoint` objects.
|
||||
"""
|
||||
|
||||
queryset = topologie.AccessPoint.objects.all()
|
||||
serializer_class = serializers.AccessPointSerializer
|
||||
|
||||
|
@ -374,6 +416,7 @@ class AccessPointViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class SwitchViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `topologie.models.Switch` objects.
|
||||
"""
|
||||
|
||||
queryset = topologie.Switch.objects.all()
|
||||
serializer_class = serializers.SwitchSerializer
|
||||
|
||||
|
@ -381,6 +424,7 @@ class SwitchViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class ServerViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `topologie.models.Server` objects.
|
||||
"""
|
||||
|
||||
queryset = topologie.Server.objects.all()
|
||||
serializer_class = serializers.ServerSerializer
|
||||
|
||||
|
@ -388,6 +432,7 @@ class ServerViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class ModelSwitchViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `topologie.models.ModelSwitch` objects.
|
||||
"""
|
||||
|
||||
queryset = topologie.ModelSwitch.objects.all()
|
||||
serializer_class = serializers.ModelSwitchSerializer
|
||||
|
||||
|
@ -396,6 +441,7 @@ class ConstructorSwitchViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
"""Exposes list and details of `topologie.models.ConstructorSwitch`
|
||||
objects.
|
||||
"""
|
||||
|
||||
queryset = topologie.ConstructorSwitch.objects.all()
|
||||
serializer_class = serializers.ConstructorSwitchSerializer
|
||||
|
||||
|
@ -403,6 +449,7 @@ class ConstructorSwitchViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class SwitchBayViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `topologie.models.SwitchBay` objects.
|
||||
"""
|
||||
|
||||
queryset = topologie.SwitchBay.objects.all()
|
||||
serializer_class = serializers.SwitchBaySerializer
|
||||
|
||||
|
@ -410,6 +457,7 @@ class SwitchBayViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class BuildingViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `topologie.models.Building` objects.
|
||||
"""
|
||||
|
||||
queryset = topologie.Building.objects.all()
|
||||
serializer_class = serializers.BuildingSerializer
|
||||
|
||||
|
@ -417,6 +465,7 @@ class BuildingViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class SwitchPortViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `topologie.models.Port` objects.
|
||||
"""
|
||||
|
||||
queryset = topologie.Port.objects.all()
|
||||
serializer_class = serializers.SwitchPortSerializer
|
||||
|
||||
|
@ -424,6 +473,7 @@ class SwitchPortViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class PortProfileViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `topologie.models.PortProfile` objects.
|
||||
"""
|
||||
|
||||
queryset = topologie.PortProfile.objects.all()
|
||||
serializer_class = serializers.PortProfileSerializer
|
||||
|
||||
|
@ -431,6 +481,7 @@ class PortProfileViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class RoomViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `topologie.models.Room` objects.
|
||||
"""
|
||||
|
||||
queryset = topologie.Room.objects.all()
|
||||
serializer_class = serializers.RoomSerializer
|
||||
|
||||
|
@ -438,6 +489,7 @@ class RoomViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class PortProfileViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `topologie.models.PortProfile` objects.
|
||||
"""
|
||||
|
||||
queryset = topologie.PortProfile.objects.all()
|
||||
serializer_class = serializers.PortProfileSerializer
|
||||
|
||||
|
@ -448,6 +500,7 @@ class PortProfileViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class UserViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `users.models.Users` objects.
|
||||
"""
|
||||
|
||||
queryset = users.User.objects.all()
|
||||
serializer_class = serializers.UserSerializer
|
||||
|
||||
|
@ -455,18 +508,25 @@ class UserViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class HomeCreationViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""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
|
||||
|
||||
|
||||
class NormalUserViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes infos of `users.models.Users`without specific rights objects."""
|
||||
|
||||
queryset = users.User.objects.exclude(groups__listright__critical=True).distinct()
|
||||
serializer_class = serializers.BasicUserSerializer
|
||||
|
||||
|
||||
class CriticalUserViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes infos of `users.models.Users`without specific rights objects."""
|
||||
|
||||
queryset = users.User.objects.filter(groups__listright__critical=True).distinct()
|
||||
serializer_class = serializers.BasicUserSerializer
|
||||
|
||||
|
@ -474,6 +534,7 @@ class CriticalUserViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class ClubViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `users.models.Club` objects.
|
||||
"""
|
||||
|
||||
queryset = users.Club.objects.all()
|
||||
serializer_class = serializers.ClubSerializer
|
||||
|
||||
|
@ -481,6 +542,7 @@ class ClubViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class AdherentViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `users.models.Adherent` objects.
|
||||
"""
|
||||
|
||||
queryset = users.Adherent.objects.all()
|
||||
serializer_class = serializers.AdherentSerializer
|
||||
|
||||
|
@ -488,6 +550,7 @@ class AdherentViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class ServiceUserViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `users.models.ServiceUser` objects.
|
||||
"""
|
||||
|
||||
queryset = users.ServiceUser.objects.all()
|
||||
serializer_class = serializers.ServiceUserSerializer
|
||||
|
||||
|
@ -495,6 +558,7 @@ class ServiceUserViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class SchoolViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `users.models.School` objects.
|
||||
"""
|
||||
|
||||
queryset = users.School.objects.all()
|
||||
serializer_class = serializers.SchoolSerializer
|
||||
|
||||
|
@ -502,6 +566,7 @@ class SchoolViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class ListRightViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `users.models.ListRight` objects.
|
||||
"""
|
||||
|
||||
queryset = users.ListRight.objects.all()
|
||||
serializer_class = serializers.ListRightSerializer
|
||||
|
||||
|
@ -509,6 +574,7 @@ class ListRightViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class ShellViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `users.models.ListShell` objects.
|
||||
"""
|
||||
|
||||
queryset = users.ListShell.objects.all()
|
||||
serializer_class = serializers.ShellSerializer
|
||||
|
||||
|
@ -516,6 +582,7 @@ class ShellViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class BanViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `users.models.Ban` objects.
|
||||
"""
|
||||
|
||||
queryset = users.Ban.objects.all()
|
||||
serializer_class = serializers.BanSerializer
|
||||
|
||||
|
@ -523,6 +590,7 @@ class BanViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class WhitelistViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `users.models.Whitelist` objects.
|
||||
"""
|
||||
|
||||
queryset = users.Whitelist.objects.all()
|
||||
serializer_class = serializers.WhitelistSerializer
|
||||
|
||||
|
@ -530,14 +598,13 @@ class WhitelistViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class EMailAddressViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `users.models.EMailAddress` objects.
|
||||
"""
|
||||
|
||||
serializer_class = serializers.EMailAddressSerializer
|
||||
queryset = users.EMailAddress.objects.none()
|
||||
|
||||
def get_queryset(self):
|
||||
if preferences.OptionalUser.get_cached_value(
|
||||
'local_email_accounts_enabled'):
|
||||
return (users.EMailAddress.objects
|
||||
.filter(user__local_email_enabled=True))
|
||||
if preferences.OptionalUser.get_cached_value("local_email_accounts_enabled"):
|
||||
return users.EMailAddress.objects.filter(user__local_email_enabled=True)
|
||||
else:
|
||||
return users.EMailAddress.objects.none()
|
||||
|
||||
|
@ -548,34 +615,47 @@ class EMailAddressViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
class ServiceRegenViewSet(viewsets.ModelViewSet):
|
||||
"""Exposes list and details of the services to regen
|
||||
"""
|
||||
|
||||
serializer_class = serializers.ServiceRegenSerializer
|
||||
|
||||
def get_queryset(self):
|
||||
queryset = machines.Service_link.objects.select_related(
|
||||
'server__domain'
|
||||
).select_related(
|
||||
'service'
|
||||
)
|
||||
if 'hostname' in self.request.GET:
|
||||
hostname = self.request.GET['hostname']
|
||||
"server__domain"
|
||||
).select_related("service")
|
||||
if "hostname" in self.request.GET:
|
||||
hostname = self.request.GET["hostname"]
|
||||
queryset = queryset.filter(server__domain__name__iexact=hostname)
|
||||
return queryset
|
||||
|
||||
|
||||
# Config des switches
|
||||
|
||||
|
||||
class SwitchPortView(generics.ListAPIView):
|
||||
"""Output each port of a switch, to be serialized with
|
||||
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
|
||||
|
||||
|
||||
# Rappel fin adhésion
|
||||
|
||||
|
||||
class ReminderView(generics.ListAPIView):
|
||||
"""Output for users to remind an end of their subscription.
|
||||
"""
|
||||
|
||||
queryset = preferences.Reminder.objects.all()
|
||||
serializer_class = serializers.ReminderSerializer
|
||||
|
||||
|
@ -583,7 +663,8 @@ class ReminderView(generics.ListAPIView):
|
|||
class RoleView(generics.ListAPIView):
|
||||
"""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
|
||||
|
||||
|
||||
|
@ -593,13 +674,12 @@ class RoleView(generics.ListAPIView):
|
|||
class LocalEmailUsersView(generics.ListAPIView):
|
||||
"""Exposes all the aliases of the users that activated the internal address
|
||||
"""
|
||||
|
||||
serializer_class = serializers.LocalEmailUsersSerializer
|
||||
|
||||
def get_queryset(self):
|
||||
if preferences.OptionalUser.get_cached_value(
|
||||
'local_email_accounts_enabled'):
|
||||
return (users.User.objects
|
||||
.filter(local_email_enabled=True))
|
||||
if preferences.OptionalUser.get_cached_value("local_email_accounts_enabled"):
|
||||
return users.User.objects.filter(local_email_enabled=True)
|
||||
else:
|
||||
return users.User.objects.none()
|
||||
|
||||
|
@ -611,6 +691,7 @@ class HostMacIpView(generics.ListAPIView):
|
|||
"""Exposes the associations between hostname, mac address and IPv4 in
|
||||
order to build the DHCP lease files.
|
||||
"""
|
||||
|
||||
serializer_class = serializers.HostMacIpSerializer
|
||||
|
||||
def get_queryset(self):
|
||||
|
@ -619,6 +700,7 @@ class HostMacIpView(generics.ListAPIView):
|
|||
|
||||
# Firewall
|
||||
|
||||
|
||||
class SubnetPortsOpenView(generics.ListAPIView):
|
||||
queryset = machines.IpType.objects.all()
|
||||
serializer_class = serializers.SubnetPortsOpenSerializer
|
||||
|
@ -636,14 +718,19 @@ class DNSZonesView(generics.ListAPIView):
|
|||
"""Exposes the detailed information about each extension (hostnames,
|
||||
IPs, DNS records, etc.) in order to build the DNS zone files.
|
||||
"""
|
||||
queryset = (machines.Extension.objects
|
||||
.prefetch_related('soa')
|
||||
.prefetch_related('ns_set').prefetch_related('ns_set__ns')
|
||||
.prefetch_related('origin')
|
||||
.prefetch_related('mx_set').prefetch_related('mx_set__name')
|
||||
.prefetch_related('txt_set')
|
||||
.prefetch_related('srv_set').prefetch_related('srv_set__target')
|
||||
.all())
|
||||
|
||||
queryset = (
|
||||
machines.Extension.objects.prefetch_related("soa")
|
||||
.prefetch_related("ns_set")
|
||||
.prefetch_related("ns_set__ns")
|
||||
.prefetch_related("origin")
|
||||
.prefetch_related("mx_set")
|
||||
.prefetch_related("mx_set__name")
|
||||
.prefetch_related("txt_set")
|
||||
.prefetch_related("srv_set")
|
||||
.prefetch_related("srv_set__target")
|
||||
.all()
|
||||
)
|
||||
serializer_class = serializers.DNSZonesSerializer
|
||||
|
||||
|
||||
|
@ -651,7 +738,8 @@ class DNSReverseZonesView(generics.ListAPIView):
|
|||
"""Exposes the detailed information about each extension (hostnames,
|
||||
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
|
||||
|
||||
|
||||
|
@ -662,13 +750,16 @@ class StandardMailingView(views.APIView):
|
|||
"""Exposes list and details of standard mailings (name and members) in
|
||||
order to building the corresponding mailing lists.
|
||||
"""
|
||||
|
||||
pagination_class = PageSizedPagination
|
||||
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):
|
||||
adherents_data = serializers.MailingMemberSerializer(all_has_access(), many=True).data
|
||||
data = [{'name': 'adherents', 'members': adherents_data}]
|
||||
adherents_data = serializers.MailingMemberSerializer(
|
||||
all_has_access(), many=True
|
||||
).data
|
||||
data = [{"name": "adherents", "members": adherents_data}]
|
||||
paginator = self.pagination_class()
|
||||
paginator.paginate_queryset(data, request)
|
||||
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
|
||||
order to build the corresponding mailing lists.
|
||||
"""
|
||||
|
||||
queryset = users.Club.objects.all()
|
||||
serializer_class = serializers.MailingSerializer
|
||||
|
||||
|
@ -696,12 +788,10 @@ class ObtainExpiringAuthToken(ObtainAuthToken):
|
|||
def post(self, request, *args, **kwargs):
|
||||
serializer = self.serializer_class(data=request.data)
|
||||
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_duration = datetime.timedelta(
|
||||
seconds=settings.API_TOKEN_DURATION
|
||||
)
|
||||
token_duration = datetime.timedelta(seconds=settings.API_TOKEN_DURATION)
|
||||
utc_now = datetime.datetime.now(datetime.timezone.utc)
|
||||
if not created and token.created < utc_now - token_duration:
|
||||
token.delete()
|
||||
|
@ -709,7 +799,6 @@ class ObtainExpiringAuthToken(ObtainAuthToken):
|
|||
token.created = datetime.datetime.utcnow()
|
||||
token.save()
|
||||
|
||||
return Response({
|
||||
'token': token.key,
|
||||
'expiration': token.created + token_duration
|
||||
})
|
||||
return Response(
|
||||
{"token": token.key, "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
|
||||
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:
|
||||
return can, None, ('cotisations',)
|
||||
return can, None, ("cotisations",)
|
||||
else:
|
||||
return (
|
||||
can,
|
||||
_("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 admin d'une facture, tous les champs"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class CostEstimateAdmin(VersionAdmin):
|
||||
"""Admin class for cost estimates."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class CustomInvoiceAdmin(VersionAdmin):
|
||||
"""Admin class for custom invoices."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class VenteAdmin(VersionAdmin):
|
||||
"""Class admin d'une vente, tous les champs (facture related)"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class ArticleAdmin(VersionAdmin):
|
||||
"""Class admin d'un article en vente"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class BanqueAdmin(VersionAdmin):
|
||||
"""Class admin de la liste des banques (facture related)"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class PaiementAdmin(VersionAdmin):
|
||||
"""Class admin d'un moyen de paiement (facture related"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class CotisationAdmin(VersionAdmin):
|
||||
"""Class admin d'une cotisation (date de debut et de fin),
|
||||
Vente related"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
|
|
|
@ -47,8 +47,13 @@ from django.shortcuts import get_object_or_404
|
|||
from re2o.field_permissions import FieldPermissionFormMixin
|
||||
from re2o.mixins import FormRevMixin
|
||||
from .models import (
|
||||
Article, Paiement, Facture, Banque,
|
||||
CustomInvoice, Vente, CostEstimate,
|
||||
Article,
|
||||
Paiement,
|
||||
Facture,
|
||||
Banque,
|
||||
CustomInvoice,
|
||||
Vente,
|
||||
CostEstimate,
|
||||
)
|
||||
from .payment_methods import balance
|
||||
|
||||
|
@ -59,31 +64,27 @@ class FactureForm(FieldPermissionFormMixin, FormRevMixin, ModelForm):
|
|||
"""
|
||||
|
||||
def __init__(self, *args, creation=False, **kwargs):
|
||||
user = kwargs['user']
|
||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
||||
user = kwargs["user"]
|
||||
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||
super(FactureForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||
self.fields['paiement'].empty_label = \
|
||||
_("Select a payment method")
|
||||
self.fields['paiement'].queryset = Paiement.find_allowed_payments(user)
|
||||
self.fields["paiement"].empty_label = _("Select a payment method")
|
||||
self.fields["paiement"].queryset = Paiement.find_allowed_payments(user)
|
||||
if not creation:
|
||||
self.fields['user'].label = _("Member")
|
||||
self.fields['user'].empty_label = \
|
||||
_("Select the proprietary member")
|
||||
self.fields['valid'].label = _("Validated invoice")
|
||||
self.fields["user"].label = _("Member")
|
||||
self.fields["user"].empty_label = _("Select the proprietary member")
|
||||
self.fields["valid"].label = _("Validated invoice")
|
||||
else:
|
||||
self.fields = {'paiement': self.fields['paiement']}
|
||||
self.fields = {"paiement": self.fields["paiement"]}
|
||||
|
||||
class Meta:
|
||||
model = Facture
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super(FactureForm, self).clean()
|
||||
paiement = cleaned_data.get('paiement')
|
||||
paiement = cleaned_data.get("paiement")
|
||||
if not paiement:
|
||||
raise forms.ValidationError(
|
||||
_("A payment method must be specified.")
|
||||
)
|
||||
raise forms.ValidationError(_("A payment method must be specified."))
|
||||
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
|
||||
member.
|
||||
"""
|
||||
|
||||
article = forms.ModelChoiceField(
|
||||
queryset=Article.objects.none(),
|
||||
label=_("Article"),
|
||||
required=True
|
||||
queryset=Article.objects.none(), label=_("Article"), required=True
|
||||
)
|
||||
quantity = forms.IntegerField(
|
||||
label=_("Quantity"),
|
||||
validators=[MinValueValidator(1)],
|
||||
required=True
|
||||
label=_("Quantity"), validators=[MinValueValidator(1)], required=True
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
user = kwargs.pop('user')
|
||||
target_user = kwargs.pop('target_user', None)
|
||||
user = kwargs.pop("user")
|
||||
target_user = kwargs.pop("target_user", None)
|
||||
super(SelectArticleForm, self).__init__(*args, **kwargs)
|
||||
self.fields['article'].queryset = Article.find_allowed_articles(
|
||||
user, target_user)
|
||||
self.fields["article"].queryset = Article.find_allowed_articles(
|
||||
user, target_user
|
||||
)
|
||||
|
||||
|
||||
class DiscountForm(Form):
|
||||
"""
|
||||
Form used in oder to create a discount on an invoice.
|
||||
"""
|
||||
|
||||
is_relative = forms.BooleanField(
|
||||
label=_("Discount is on percentage."),
|
||||
required=False,
|
||||
label=_("Discount is on percentage."), required=False
|
||||
)
|
||||
discount = forms.DecimalField(
|
||||
label=_("Discount"),
|
||||
|
@ -130,53 +129,51 @@ class DiscountForm(Form):
|
|||
|
||||
def apply_to_invoice(self, invoice):
|
||||
invoice_price = invoice.prix_total()
|
||||
discount = self.cleaned_data['discount']
|
||||
is_relative = self.cleaned_data['is_relative']
|
||||
discount = self.cleaned_data["discount"]
|
||||
is_relative = self.cleaned_data["is_relative"]
|
||||
if is_relative:
|
||||
amount = discount/100 * invoice_price
|
||||
amount = discount / 100 * invoice_price
|
||||
else:
|
||||
amount = discount
|
||||
if amount:
|
||||
name = _("{}% discount") if is_relative else _("{}€ discount")
|
||||
name = name.format(discount)
|
||||
Vente.objects.create(
|
||||
facture=invoice,
|
||||
name=name,
|
||||
prix=-amount,
|
||||
number=1
|
||||
)
|
||||
Vente.objects.create(facture=invoice, name=name, prix=-amount, number=1)
|
||||
|
||||
|
||||
class CustomInvoiceForm(FormRevMixin, ModelForm):
|
||||
"""
|
||||
Form used to create a custom invoice.
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = CustomInvoice
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class CostEstimateForm(FormRevMixin, ModelForm):
|
||||
"""
|
||||
Form used to create a cost estimate.
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = CostEstimate
|
||||
exclude = ['paid', 'final_invoice']
|
||||
exclude = ["paid", "final_invoice"]
|
||||
|
||||
|
||||
class ArticleForm(FormRevMixin, ModelForm):
|
||||
"""
|
||||
Form used to create an article.
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = Article
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
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)
|
||||
self.fields['name'].label = _("Article name")
|
||||
self.fields["name"].label = _("Article name")
|
||||
|
||||
|
||||
class DelArticleForm(FormRevMixin, Form):
|
||||
|
@ -184,19 +181,20 @@ class DelArticleForm(FormRevMixin, Form):
|
|||
Form used to delete one or more of the currently available articles.
|
||||
The user must choose the one to delete by checking the boxes.
|
||||
"""
|
||||
|
||||
articles = forms.ModelMultipleChoiceField(
|
||||
queryset=Article.objects.none(),
|
||||
label=_("Available articles"),
|
||||
widget=forms.CheckboxSelectMultiple
|
||||
widget=forms.CheckboxSelectMultiple,
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
instances = kwargs.pop('instances', None)
|
||||
instances = kwargs.pop("instances", None)
|
||||
super(DelArticleForm, self).__init__(*args, **kwargs)
|
||||
if instances:
|
||||
self.fields['articles'].queryset = instances
|
||||
self.fields["articles"].queryset = instances
|
||||
else:
|
||||
self.fields['articles'].queryset = Article.objects.all()
|
||||
self.fields["articles"].queryset = Article.objects.all()
|
||||
|
||||
|
||||
# TODO : change Paiement to Payment
|
||||
|
@ -206,15 +204,16 @@ class PaiementForm(FormRevMixin, ModelForm):
|
|||
The 'cheque' type is used to associate a specific behaviour requiring
|
||||
a cheque number and a bank.
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = Paiement
|
||||
# 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):
|
||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
||||
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||
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
|
||||
|
@ -223,20 +222,21 @@ class DelPaiementForm(FormRevMixin, Form):
|
|||
Form used to delete one or more payment methods.
|
||||
The user must choose the one to delete by checking the boxes.
|
||||
"""
|
||||
|
||||
# TODO : change paiement to payment
|
||||
paiements = forms.ModelMultipleChoiceField(
|
||||
queryset=Paiement.objects.none(),
|
||||
label=_("Available payment methods"),
|
||||
widget=forms.CheckboxSelectMultiple
|
||||
widget=forms.CheckboxSelectMultiple,
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
instances = kwargs.pop('instances', None)
|
||||
instances = kwargs.pop("instances", None)
|
||||
super(DelPaiementForm, self).__init__(*args, **kwargs)
|
||||
if instances:
|
||||
self.fields['paiements'].queryset = instances
|
||||
self.fields["paiements"].queryset = instances
|
||||
else:
|
||||
self.fields['paiements'].queryset = Paiement.objects.all()
|
||||
self.fields["paiements"].queryset = Paiement.objects.all()
|
||||
|
||||
|
||||
# TODO : change banque to bank
|
||||
|
@ -244,15 +244,16 @@ class BanqueForm(FormRevMixin, ModelForm):
|
|||
"""
|
||||
Form used to create a bank.
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
# TODO : change banque to bank
|
||||
model = Banque
|
||||
fields = ['name']
|
||||
fields = ["name"]
|
||||
|
||||
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)
|
||||
self.fields['name'].label = _("Bank name")
|
||||
self.fields["name"].label = _("Bank name")
|
||||
|
||||
|
||||
# TODO : change banque to bank
|
||||
|
@ -261,20 +262,21 @@ class DelBanqueForm(FormRevMixin, Form):
|
|||
Form used to delete one or more banks.
|
||||
The use must choose the one to delete by checking the boxes.
|
||||
"""
|
||||
|
||||
# TODO : change banque to bank
|
||||
banques = forms.ModelMultipleChoiceField(
|
||||
queryset=Banque.objects.none(),
|
||||
label=_("Available banks"),
|
||||
widget=forms.CheckboxSelectMultiple
|
||||
widget=forms.CheckboxSelectMultiple,
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
instances = kwargs.pop('instances', None)
|
||||
instances = kwargs.pop("instances", None)
|
||||
super(DelBanqueForm, self).__init__(*args, **kwargs)
|
||||
if instances:
|
||||
self.fields['banques'].queryset = instances
|
||||
self.fields["banques"].queryset = instances
|
||||
else:
|
||||
self.fields['banques'].queryset = Banque.objects.all()
|
||||
self.fields["banques"].queryset = Banque.objects.all()
|
||||
|
||||
|
||||
# TODO : Better name and docstring
|
||||
|
@ -282,36 +284,36 @@ class RechargeForm(FormRevMixin, Form):
|
|||
"""
|
||||
Form used to refill a user's balance
|
||||
"""
|
||||
value = forms.DecimalField(
|
||||
label=_("Amount"),
|
||||
decimal_places=2,
|
||||
)
|
||||
|
||||
value = forms.DecimalField(label=_("Amount"), decimal_places=2)
|
||||
payment = forms.ModelChoiceField(
|
||||
queryset=Paiement.objects.none(),
|
||||
label=_("Payment method")
|
||||
queryset=Paiement.objects.none(), label=_("Payment method")
|
||||
)
|
||||
|
||||
def __init__(self, *args, user=None, user_source=None, **kwargs):
|
||||
self.user = user
|
||||
super(RechargeForm, self).__init__(*args, **kwargs)
|
||||
self.fields['payment'].empty_label = \
|
||||
_("Select a payment method")
|
||||
self.fields['payment'].queryset = Paiement.find_allowed_payments(
|
||||
user_source).exclude(is_balance=True)
|
||||
self.fields["payment"].empty_label = _("Select a payment method")
|
||||
self.fields["payment"].queryset = Paiement.find_allowed_payments(
|
||||
user_source
|
||||
).exclude(is_balance=True)
|
||||
|
||||
def clean(self):
|
||||
"""
|
||||
Returns a cleaned value from the received form by validating
|
||||
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)
|
||||
if balance_method.maximum_balance is not None and \
|
||||
value + self.user.solde > balance_method.maximum_balance:
|
||||
if (
|
||||
balance_method.maximum_balance is not None
|
||||
and value + self.user.solde > balance_method.maximum_balance
|
||||
):
|
||||
raise forms.ValidationError(
|
||||
_("Requested amount is too high. Your balance can't exceed"
|
||||
" %(max_online_balance)s €.") % {
|
||||
'max_online_balance': balance_method.maximum_balance
|
||||
}
|
||||
_(
|
||||
"Requested amount is too high. Your balance can't exceed"
|
||||
" %(max_online_balance)s €."
|
||||
)
|
||||
% {"max_online_balance": balance_method.maximum_balance}
|
||||
)
|
||||
return self.cleaned_data
|
||||
|
|
|
@ -29,54 +29,100 @@ import django.db.models.deletion
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('users', '0005_auto_20160702_0006'),
|
||||
]
|
||||
dependencies = [("users", "0005_auto_20160702_0006")]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Article',
|
||||
name="Article",
|
||||
fields=[
|
||||
('id', 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)),
|
||||
(
|
||||
"id",
|
||||
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(
|
||||
name='Banque',
|
||||
name="Banque",
|
||||
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(
|
||||
name='Facture',
|
||||
name="Facture",
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', auto_created=True, primary_key=True, serialize=False)),
|
||||
('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)),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
verbose_name="ID",
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
),
|
||||
),
|
||||
("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(
|
||||
name='Paiement',
|
||||
name="Paiement",
|
||||
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(
|
||||
model_name='facture',
|
||||
name='paiement',
|
||||
field=models.ForeignKey(to='cotisations.Paiement', on_delete=django.db.models.deletion.PROTECT),
|
||||
model_name="facture",
|
||||
name="paiement",
|
||||
field=models.ForeignKey(
|
||||
to="cotisations.Paiement", on_delete=django.db.models.deletion.PROTECT
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='facture',
|
||||
name='user',
|
||||
field=models.ForeignKey(to='users.User', on_delete=django.db.models.deletion.PROTECT),
|
||||
model_name="facture",
|
||||
name="user",
|
||||
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):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0001_initial'),
|
||||
]
|
||||
dependencies = [("cotisations", "0001_initial")]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='facture',
|
||||
name='article',
|
||||
),
|
||||
]
|
||||
operations = [migrations.RemoveField(model_name="facture", name="article")]
|
||||
|
|
|
@ -29,14 +29,17 @@ import django.db.models.deletion
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0002_remove_facture_article'),
|
||||
]
|
||||
dependencies = [("cotisations", "0002_remove_facture_article")]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='facture',
|
||||
name='banque',
|
||||
field=models.ForeignKey(blank=True, to='cotisations.Banque', on_delete=django.db.models.deletion.PROTECT, null=True),
|
||||
),
|
||||
model_name="facture",
|
||||
name="banque",
|
||||
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):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0003_auto_20160702_1448'),
|
||||
]
|
||||
dependencies = [("cotisations", "0003_auto_20160702_1448")]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='facture',
|
||||
name='name',
|
||||
model_name="facture",
|
||||
name="name",
|
||||
field=models.CharField(null=True, max_length=255),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='facture',
|
||||
name='prix',
|
||||
model_name="facture",
|
||||
name="prix",
|
||||
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):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0004_auto_20160702_1528'),
|
||||
]
|
||||
dependencies = [("cotisations", "0004_auto_20160702_1528")]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='facture',
|
||||
name='cheque',
|
||||
model_name="facture",
|
||||
name="cheque",
|
||||
field=models.CharField(max_length=255, blank=True),
|
||||
),
|
||||
)
|
||||
]
|
||||
|
|
|
@ -28,19 +28,19 @@ from django.db import migrations, models
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0005_auto_20160702_1532'),
|
||||
]
|
||||
dependencies = [("cotisations", "0005_auto_20160702_1532")]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='facture',
|
||||
name='name',
|
||||
field=models.CharField(null=True, default='plop', max_length=255),
|
||||
model_name="facture",
|
||||
name="name",
|
||||
field=models.CharField(null=True, default="plop", max_length=255),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='facture',
|
||||
name='prix',
|
||||
field=models.DecimalField(null=True, decimal_places=2, default=1, max_digits=5),
|
||||
model_name="facture",
|
||||
name="prix",
|
||||
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):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0006_auto_20160702_1534'),
|
||||
]
|
||||
dependencies = [("cotisations", "0006_auto_20160702_1534")]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='facture',
|
||||
name='name',
|
||||
field=models.CharField(default='plop', max_length=255),
|
||||
model_name="facture",
|
||||
name="name",
|
||||
field=models.CharField(default="plop", max_length=255),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='facture',
|
||||
name='prix',
|
||||
model_name="facture",
|
||||
name="prix",
|
||||
field=models.DecimalField(default=1, max_digits=5, decimal_places=2),
|
||||
preserve_default=False,
|
||||
),
|
||||
|
|
|
@ -30,43 +30,53 @@ import django.db.models.deletion
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('users', '0005_auto_20160702_0006'),
|
||||
('cotisations', '0007_auto_20160702_1543'),
|
||||
("users", "0005_auto_20160702_0006"),
|
||||
("cotisations", "0007_auto_20160702_1543"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Cotisation',
|
||||
name="Cotisation",
|
||||
fields=[
|
||||
('id', 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()),
|
||||
(
|
||||
"id",
|
||||
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(
|
||||
model_name='article',
|
||||
name='cotisation',
|
||||
model_name="article",
|
||||
name="cotisation",
|
||||
field=models.BooleanField(default=True),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='article',
|
||||
name='duration',
|
||||
model_name="article",
|
||||
name="duration",
|
||||
field=models.DurationField(blank=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='facture',
|
||||
name='valid',
|
||||
field=models.BooleanField(default=True),
|
||||
model_name="facture", name="valid", field=models.BooleanField(default=True)
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='cotisation',
|
||||
name='facture',
|
||||
field=models.ForeignKey(to='cotisations.Facture', on_delete=django.db.models.deletion.PROTECT),
|
||||
model_name="cotisation",
|
||||
name="facture",
|
||||
field=models.ForeignKey(
|
||||
to="cotisations.Facture", on_delete=django.db.models.deletion.PROTECT
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='cotisation',
|
||||
name='user',
|
||||
field=models.ForeignKey(to='users.User', on_delete=django.db.models.deletion.PROTECT),
|
||||
model_name="cotisation",
|
||||
name="user",
|
||||
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):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0008_auto_20160702_1614'),
|
||||
]
|
||||
dependencies = [("cotisations", "0008_auto_20160702_1614")]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='cotisation',
|
||||
name='user',
|
||||
),
|
||||
]
|
||||
operations = [migrations.RemoveField(model_name="cotisation", name="user")]
|
||||
|
|
|
@ -28,18 +28,15 @@ from django.db import migrations, models
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0009_remove_cotisation_user'),
|
||||
]
|
||||
dependencies = [("cotisations", "0009_remove_cotisation_user")]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='article',
|
||||
name='duration',
|
||||
),
|
||||
migrations.RemoveField(model_name="article", name="duration"),
|
||||
migrations.AddField(
|
||||
model_name='article',
|
||||
name='duration',
|
||||
field=models.IntegerField(null=True, help_text='Durée exprimée en mois entiers', blank=True),
|
||||
model_name="article",
|
||||
name="duration",
|
||||
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):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0010_auto_20160702_1840'),
|
||||
]
|
||||
dependencies = [("cotisations", "0010_auto_20160702_1840")]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='cotisation',
|
||||
name='date_start',
|
||||
field=models.DateTimeField(),
|
||||
),
|
||||
model_name="cotisation", name="date_start", field=models.DateTimeField()
|
||||
)
|
||||
]
|
||||
|
|
|
@ -29,14 +29,14 @@ import django.db.models.deletion
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0011_auto_20160702_1911'),
|
||||
]
|
||||
dependencies = [("cotisations", "0011_auto_20160702_1911")]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='cotisation',
|
||||
name='facture',
|
||||
field=models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='cotisations.Facture'),
|
||||
),
|
||||
model_name="cotisation",
|
||||
name="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):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0012_auto_20160704_0118'),
|
||||
]
|
||||
dependencies = [("cotisations", "0012_auto_20160704_0118")]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Vente',
|
||||
name="Vente",
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, 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')),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
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(
|
||||
model_name='facture',
|
||||
name='name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='facture',
|
||||
name='prix',
|
||||
),
|
||||
migrations.RemoveField(model_name="facture", name="name"),
|
||||
migrations.RemoveField(model_name="facture", name="prix"),
|
||||
migrations.AddField(
|
||||
model_name='vente',
|
||||
name='facture',
|
||||
field=models.ForeignKey(to='cotisations.Facture', on_delete=django.db.models.deletion.PROTECT),
|
||||
model_name="vente",
|
||||
name="facture",
|
||||
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):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0013_auto_20160711_2240'),
|
||||
]
|
||||
dependencies = [("cotisations", "0013_auto_20160711_2240")]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='facture',
|
||||
name='number',
|
||||
),
|
||||
migrations.RemoveField(model_name="facture", name="number"),
|
||||
migrations.AddField(
|
||||
model_name='vente',
|
||||
name='number',
|
||||
model_name="vente",
|
||||
name="number",
|
||||
field=models.IntegerField(default=1),
|
||||
preserve_default=False,
|
||||
),
|
||||
|
|
|
@ -29,29 +29,29 @@ import django.core.validators
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0014_auto_20160712_0245'),
|
||||
]
|
||||
dependencies = [("cotisations", "0014_auto_20160712_0245")]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='facture',
|
||||
name='control',
|
||||
model_name="facture",
|
||||
name="control",
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cotisation',
|
||||
name='facture',
|
||||
field=models.OneToOneField(to='cotisations.Facture'),
|
||||
model_name="cotisation",
|
||||
name="facture",
|
||||
field=models.OneToOneField(to="cotisations.Facture"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='vente',
|
||||
name='facture',
|
||||
field=models.ForeignKey(to='cotisations.Facture'),
|
||||
model_name="vente",
|
||||
name="facture",
|
||||
field=models.ForeignKey(to="cotisations.Facture"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='vente',
|
||||
name='number',
|
||||
field=models.IntegerField(validators=[django.core.validators.MinValueValidator(1)]),
|
||||
model_name="vente",
|
||||
name="number",
|
||||
field=models.IntegerField(
|
||||
validators=[django.core.validators.MinValueValidator(1)]
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -28,29 +28,20 @@ from django.db import migrations, models
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0015_auto_20160714_2142'),
|
||||
]
|
||||
dependencies = [("cotisations", "0015_auto_20160714_2142")]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name='article',
|
||||
old_name='cotisation',
|
||||
new_name='iscotisation',
|
||||
model_name="article", old_name="cotisation", new_name="iscotisation"
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name='vente',
|
||||
old_name='cotisation',
|
||||
new_name='iscotisation',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='cotisation',
|
||||
name='facture',
|
||||
model_name="vente", old_name="cotisation", new_name="iscotisation"
|
||||
),
|
||||
migrations.RemoveField(model_name="cotisation", name="facture"),
|
||||
migrations.AddField(
|
||||
model_name='cotisation',
|
||||
name='vente',
|
||||
field=models.OneToOneField(to='cotisations.Vente', null=True),
|
||||
model_name="cotisation",
|
||||
name="vente",
|
||||
field=models.OneToOneField(to="cotisations.Vente", null=True),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
||||
|
|
|
@ -8,19 +8,22 @@ from django.db import migrations, models
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0016_auto_20160715_0110'),
|
||||
]
|
||||
dependencies = [("cotisations", "0016_auto_20160715_0110")]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='article',
|
||||
name='duration',
|
||||
field=models.IntegerField(blank=True, help_text='Durée exprimée en mois entiers', null=True, validators=[django.core.validators.MinValueValidator(0)]),
|
||||
model_name="article",
|
||||
name="duration",
|
||||
field=models.IntegerField(
|
||||
blank=True,
|
||||
help_text="Durée exprimée en mois entiers",
|
||||
null=True,
|
||||
validators=[django.core.validators.MinValueValidator(0)],
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='article',
|
||||
name='name',
|
||||
model_name="article",
|
||||
name="name",
|
||||
field=models.CharField(max_length=255, unique=True),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -7,15 +7,17 @@ from django.db import migrations, models
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0017_auto_20170718_2329'),
|
||||
]
|
||||
dependencies = [("cotisations", "0017_auto_20170718_2329")]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='paiement',
|
||||
name='type_paiement',
|
||||
field=models.CharField(choices=[('check', 'Chèque'), (None, 'Autre')], default=None, max_length=255),
|
||||
model_name="paiement",
|
||||
name="type_paiement",
|
||||
field=models.CharField(
|
||||
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):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0018_paiement_type_paiement'),
|
||||
]
|
||||
dependencies = [("cotisations", "0018_paiement_type_paiement")]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='paiement',
|
||||
name='type_paiement',
|
||||
field=models.CharField(choices=[(0, 'Autre'), (1, 'Chèque')], default=0, max_length=255),
|
||||
),
|
||||
model_name="paiement",
|
||||
name="type_paiement",
|
||||
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):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0019_auto_20170819_0055'),
|
||||
]
|
||||
dependencies = [("cotisations", "0019_auto_20170819_0055")]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='paiement',
|
||||
name='type_paiement',
|
||||
field=models.IntegerField(choices=[(0, 'Autre'), (1, 'Chèque')], default=0, max_length=255),
|
||||
),
|
||||
model_name="paiement",
|
||||
name="type_paiement",
|
||||
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):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0020_auto_20170819_0057'),
|
||||
]
|
||||
dependencies = [("cotisations", "0020_auto_20170819_0057")]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='paiement',
|
||||
name='type_paiement',
|
||||
field=models.IntegerField(choices=[(0, 'Autre'), (1, 'Chèque')], default=0),
|
||||
),
|
||||
model_name="paiement",
|
||||
name="type_paiement",
|
||||
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):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0021_auto_20170819_0104'),
|
||||
]
|
||||
dependencies = [("cotisations", "0021_auto_20170819_0104")]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='paiement',
|
||||
name='type_paiement',
|
||||
field=models.IntegerField(choices=[(0, 'Autre'), (1, 'Chèque')], default=0, max_length=255),
|
||||
),
|
||||
model_name="paiement",
|
||||
name="type_paiement",
|
||||
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):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0022_auto_20170824_0128'),
|
||||
]
|
||||
dependencies = [("cotisations", "0022_auto_20170824_0128")]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='paiement',
|
||||
name='type_paiement',
|
||||
field=models.IntegerField(choices=[(0, 'Autre'), (1, 'Chèque')], default=0),
|
||||
),
|
||||
model_name="paiement",
|
||||
name="type_paiement",
|
||||
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):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0023_auto_20170902_1303'),
|
||||
]
|
||||
dependencies = [("cotisations", "0023_auto_20170902_1303")]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='article',
|
||||
name='duration',
|
||||
field=models.PositiveIntegerField(blank=True, help_text='Durée exprimée en mois entiers', null=True, validators=[django.core.validators.MinValueValidator(0)]),
|
||||
model_name="article",
|
||||
name="duration",
|
||||
field=models.PositiveIntegerField(
|
||||
blank=True,
|
||||
help_text="Durée exprimée en mois entiers",
|
||||
null=True,
|
||||
validators=[django.core.validators.MinValueValidator(0)],
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='vente',
|
||||
name='duration',
|
||||
field=models.PositiveIntegerField(blank=True, help_text='Durée exprimée en mois entiers', null=True),
|
||||
model_name="vente",
|
||||
name="duration",
|
||||
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):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0024_auto_20171015_2033'),
|
||||
]
|
||||
dependencies = [("cotisations", "0024_auto_20171015_2033")]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='article',
|
||||
name='type_user',
|
||||
field=models.CharField(choices=[('Adherent', 'Adherent'), ('Club', 'Club'), ('All', 'All')], default='All', max_length=255),
|
||||
),
|
||||
model_name="article",
|
||||
name="type_user",
|
||||
field=models.CharField(
|
||||
choices=[("Adherent", "Adherent"), ("Club", "Club"), ("All", "All")],
|
||||
default="All",
|
||||
max_length=255,
|
||||
),
|
||||
)
|
||||
]
|
||||
|
|
|
@ -6,73 +6,94 @@ from django.db import migrations, models
|
|||
|
||||
|
||||
def create_type(apps, schema_editor):
|
||||
Cotisation = apps.get_model('cotisations', 'Cotisation')
|
||||
Vente = apps.get_model('cotisations', 'Vente')
|
||||
Article = apps.get_model('cotisations', 'Article')
|
||||
Cotisation = apps.get_model("cotisations", "Cotisation")
|
||||
Vente = apps.get_model("cotisations", "Vente")
|
||||
Article = apps.get_model("cotisations", "Article")
|
||||
db_alias = schema_editor.connection.alias
|
||||
articles = Article.objects.using(db_alias).all()
|
||||
ventes = Vente.objects.using(db_alias).all()
|
||||
cotisations = Cotisation.objects.using(db_alias).all()
|
||||
for article in articles:
|
||||
if article.iscotisation:
|
||||
article.type_cotisation='All'
|
||||
article.type_cotisation = "All"
|
||||
article.save(using=db_alias)
|
||||
for vente in ventes:
|
||||
if vente.iscotisation:
|
||||
vente.type_cotisation='All'
|
||||
vente.type_cotisation = "All"
|
||||
vente.save(using=db_alias)
|
||||
for cotisation in cotisations:
|
||||
cotisation.type_cotisation='All'
|
||||
cotisation.type_cotisation = "All"
|
||||
cotisation.save(using=db_alias)
|
||||
|
||||
|
||||
def delete_type(apps, schema_editor):
|
||||
Vente = apps.get_model('cotisations', 'Vente')
|
||||
Article = apps.get_model('cotisations', 'Article')
|
||||
Vente = apps.get_model("cotisations", "Vente")
|
||||
Article = apps.get_model("cotisations", "Article")
|
||||
db_alias = schema_editor.connection.alias
|
||||
articles = Article.objects.using(db_alias).all()
|
||||
ventes = Vente.objects.using(db_alias).all()
|
||||
for article in articles:
|
||||
if article.type_cotisation:
|
||||
article.iscotisation=True
|
||||
article.iscotisation = True
|
||||
else:
|
||||
article.iscotisation=False
|
||||
article.iscotisation = False
|
||||
article.save(using=db_alias)
|
||||
for vente in ventes:
|
||||
if vente.iscotisation:
|
||||
vente.iscotisation=True
|
||||
vente.iscotisation = True
|
||||
else:
|
||||
vente.iscotisation=False
|
||||
vente.iscotisation = False
|
||||
vente.save(using=db_alias)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0025_article_type_user'),
|
||||
]
|
||||
dependencies = [("cotisations", "0025_article_type_user")]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='article',
|
||||
name='type_cotisation',
|
||||
field=models.CharField(blank=True, choices=[('Connexion', 'Connexion'), ('Adhesion', 'Adhesion'), ('All', 'All')], default=None, max_length=255, null=True),
|
||||
model_name="article",
|
||||
name="type_cotisation",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
choices=[
|
||||
("Connexion", "Connexion"),
|
||||
("Adhesion", "Adhesion"),
|
||||
("All", "All"),
|
||||
],
|
||||
default=None,
|
||||
max_length=255,
|
||||
null=True,
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='cotisation',
|
||||
name='type_cotisation',
|
||||
field=models.CharField(choices=[('Connexion', 'Connexion'), ('Adhesion', 'Adhesion'), ('All', 'All')], max_length=255, default='All'),
|
||||
model_name="cotisation",
|
||||
name="type_cotisation",
|
||||
field=models.CharField(
|
||||
choices=[
|
||||
("Connexion", "Connexion"),
|
||||
("Adhesion", "Adhesion"),
|
||||
("All", "All"),
|
||||
],
|
||||
max_length=255,
|
||||
default="All",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='vente',
|
||||
name='type_cotisation',
|
||||
field=models.CharField(blank=True, choices=[('Connexion', 'Connexion'), ('Adhesion', 'Adhesion'), ('All', 'All')], max_length=255, null=True),
|
||||
model_name="vente",
|
||||
name="type_cotisation",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
choices=[
|
||||
("Connexion", "Connexion"),
|
||||
("Adhesion", "Adhesion"),
|
||||
("All", "All"),
|
||||
],
|
||||
max_length=255,
|
||||
null=True,
|
||||
),
|
||||
),
|
||||
migrations.RunPython(create_type, delete_type),
|
||||
migrations.RemoveField(
|
||||
model_name='article',
|
||||
name='iscotisation',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='vente',
|
||||
name='iscotisation',
|
||||
),
|
||||
migrations.RemoveField(model_name="article", name="iscotisation"),
|
||||
migrations.RemoveField(model_name="vente", name="iscotisation"),
|
||||
]
|
||||
|
|
|
@ -7,14 +7,10 @@ from django.db import migrations, models
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0026_auto_20171028_0126'),
|
||||
]
|
||||
dependencies = [("cotisations", "0026_auto_20171028_0126")]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='article',
|
||||
name='name',
|
||||
field=models.CharField(max_length=255),
|
||||
),
|
||||
model_name="article", name="name", field=models.CharField(max_length=255)
|
||||
)
|
||||
]
|
||||
|
|
|
@ -7,33 +7,56 @@ from django.db import migrations
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0027_auto_20171029_1156'),
|
||||
]
|
||||
dependencies = [("cotisations", "0027_auto_20171029_1156")]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='article',
|
||||
options={'permissions': (('view_article', 'Peut voir un objet article'),)},
|
||||
name="article",
|
||||
options={"permissions": (("view_article", "Peut voir un objet article"),)},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='banque',
|
||||
options={'permissions': (('view_banque', 'Peut voir un objet banque'),)},
|
||||
name="banque",
|
||||
options={"permissions": (("view_banque", "Peut voir un objet banque"),)},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='cotisation',
|
||||
options={'permissions': (('view_cotisation', 'Peut voir un objet cotisation'), ('change_all_cotisation', 'Superdroit, peut modifier toutes les cotisations'))},
|
||||
name="cotisation",
|
||||
options={
|
||||
"permissions": (
|
||||
("view_cotisation", "Peut voir un objet cotisation"),
|
||||
(
|
||||
"change_all_cotisation",
|
||||
"Superdroit, peut modifier toutes les cotisations",
|
||||
),
|
||||
)
|
||||
},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
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'))},
|
||||
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",
|
||||
),
|
||||
)
|
||||
},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='paiement',
|
||||
options={'permissions': (('view_paiement', 'Peut voir un objet paiement'),)},
|
||||
name="paiement",
|
||||
options={
|
||||
"permissions": (("view_paiement", "Peut voir un objet paiement"),)
|
||||
},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='vente',
|
||||
options={'permissions': (('view_vente', 'Peut voir un objet vente'), ('change_all_vente', 'Superdroit, peut modifier toutes les ventes'))},
|
||||
name="vente",
|
||||
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):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0028_auto_20171231_0007'),
|
||||
]
|
||||
dependencies = [("cotisations", "0028_auto_20171231_0007")]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='article',
|
||||
options={'permissions': (('view_article', "Can see an article's details"),), 'verbose_name': 'Article', 'verbose_name_plural': 'Articles'},
|
||||
name="article",
|
||||
options={
|
||||
"permissions": (("view_article", "Can see an article's details"),),
|
||||
"verbose_name": "Article",
|
||||
"verbose_name_plural": "Articles",
|
||||
},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='banque',
|
||||
options={'permissions': (('view_banque', "Can see a bank's details"),), 'verbose_name': 'Bank', 'verbose_name_plural': 'Banks'},
|
||||
name="banque",
|
||||
options={
|
||||
"permissions": (("view_banque", "Can see a bank's details"),),
|
||||
"verbose_name": "Bank",
|
||||
"verbose_name_plural": "Banks",
|
||||
},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='cotisation',
|
||||
options={'permissions': (('view_cotisation', "Can see a cotisation's details"), ('change_all_cotisation', 'Can edit the previous cotisations'))},
|
||||
name="cotisation",
|
||||
options={
|
||||
"permissions": (
|
||||
("view_cotisation", "Can see a cotisation's details"),
|
||||
("change_all_cotisation", "Can edit the previous cotisations"),
|
||||
)
|
||||
},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
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'},
|
||||
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",
|
||||
},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='paiement',
|
||||
options={'permissions': (('view_paiement', "Can see a payement's details"),), 'verbose_name': 'Payment method', 'verbose_name_plural': 'Payment methods'},
|
||||
name="paiement",
|
||||
options={
|
||||
"permissions": (("view_paiement", "Can see a payement's details"),),
|
||||
"verbose_name": "Payment method",
|
||||
"verbose_name_plural": "Payment methods",
|
||||
},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
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'},
|
||||
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",
|
||||
},
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='article',
|
||||
name='duration',
|
||||
field=models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Duration (in whole month)'),
|
||||
model_name="article",
|
||||
name="duration",
|
||||
field=models.PositiveIntegerField(
|
||||
blank=True,
|
||||
null=True,
|
||||
validators=[django.core.validators.MinValueValidator(0)],
|
||||
verbose_name="Duration (in whole month)",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='article',
|
||||
name='name',
|
||||
field=models.CharField(max_length=255, verbose_name='Designation'),
|
||||
model_name="article",
|
||||
name="name",
|
||||
field=models.CharField(max_length=255, verbose_name="Designation"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='article',
|
||||
name='prix',
|
||||
field=models.DecimalField(decimal_places=2, max_digits=5, verbose_name='Unitary price'),
|
||||
model_name="article",
|
||||
name="prix",
|
||||
field=models.DecimalField(
|
||||
decimal_places=2, max_digits=5, verbose_name="Unitary price"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='article',
|
||||
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'),
|
||||
model_name="article",
|
||||
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",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='article',
|
||||
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'),
|
||||
model_name="article",
|
||||
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",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='banque',
|
||||
name='name',
|
||||
field=models.CharField(max_length=255, verbose_name='Name'),
|
||||
model_name="banque",
|
||||
name="name",
|
||||
field=models.CharField(max_length=255, verbose_name="Name"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cotisation',
|
||||
name='date_end',
|
||||
field=models.DateTimeField(verbose_name='Ending date'),
|
||||
model_name="cotisation",
|
||||
name="date_end",
|
||||
field=models.DateTimeField(verbose_name="Ending date"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cotisation',
|
||||
name='date_start',
|
||||
field=models.DateTimeField(verbose_name='Starting date'),
|
||||
model_name="cotisation",
|
||||
name="date_start",
|
||||
field=models.DateTimeField(verbose_name="Starting date"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='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'),
|
||||
model_name="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",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cotisation',
|
||||
name='vente',
|
||||
field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to='cotisations.Vente', verbose_name='Purchase'),
|
||||
model_name="cotisation",
|
||||
name="vente",
|
||||
field=models.OneToOneField(
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="cotisations.Vente",
|
||||
verbose_name="Purchase",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='facture',
|
||||
name='cheque',
|
||||
field=models.CharField(blank=True, max_length=255, verbose_name='Cheque number'),
|
||||
model_name="facture",
|
||||
name="cheque",
|
||||
field=models.CharField(
|
||||
blank=True, max_length=255, verbose_name="Cheque number"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='facture',
|
||||
name='control',
|
||||
field=models.BooleanField(default=False, verbose_name='Controlled'),
|
||||
model_name="facture",
|
||||
name="control",
|
||||
field=models.BooleanField(default=False, verbose_name="Controlled"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='facture',
|
||||
name='date',
|
||||
field=models.DateTimeField(auto_now_add=True, verbose_name='Date'),
|
||||
model_name="facture",
|
||||
name="date",
|
||||
field=models.DateTimeField(auto_now_add=True, verbose_name="Date"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='facture',
|
||||
name='valid',
|
||||
field=models.BooleanField(default=True, verbose_name='Validated'),
|
||||
model_name="facture",
|
||||
name="valid",
|
||||
field=models.BooleanField(default=True, verbose_name="Validated"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='paiement',
|
||||
name='moyen',
|
||||
field=models.CharField(max_length=255, verbose_name='Method'),
|
||||
model_name="paiement",
|
||||
name="moyen",
|
||||
field=models.CharField(max_length=255, verbose_name="Method"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='paiement',
|
||||
name='type_paiement',
|
||||
field=models.IntegerField(choices=[(0, 'Standard'), (1, 'Cheque')], default=0, verbose_name='Payment type'),
|
||||
model_name="paiement",
|
||||
name="type_paiement",
|
||||
field=models.IntegerField(
|
||||
choices=[(0, "Standard"), (1, "Cheque")],
|
||||
default=0,
|
||||
verbose_name="Payment type",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='vente',
|
||||
name='duration',
|
||||
field=models.PositiveIntegerField(blank=True, null=True, verbose_name='Duration (in whole month)'),
|
||||
model_name="vente",
|
||||
name="duration",
|
||||
field=models.PositiveIntegerField(
|
||||
blank=True, null=True, verbose_name="Duration (in whole month)"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='vente',
|
||||
name='facture',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cotisations.Facture', verbose_name='Invoice'),
|
||||
model_name="vente",
|
||||
name="facture",
|
||||
field=models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="cotisations.Facture",
|
||||
verbose_name="Invoice",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='vente',
|
||||
name='name',
|
||||
field=models.CharField(max_length=255, verbose_name='Article'),
|
||||
model_name="vente",
|
||||
name="name",
|
||||
field=models.CharField(max_length=255, verbose_name="Article"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='vente',
|
||||
name='number',
|
||||
field=models.IntegerField(validators=[django.core.validators.MinValueValidator(1)], verbose_name='Amount'),
|
||||
model_name="vente",
|
||||
name="number",
|
||||
field=models.IntegerField(
|
||||
validators=[django.core.validators.MinValueValidator(1)],
|
||||
verbose_name="Amount",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='vente',
|
||||
name='prix',
|
||||
field=models.DecimalField(decimal_places=2, max_digits=5, verbose_name='Price'),
|
||||
model_name="vente",
|
||||
name="prix",
|
||||
field=models.DecimalField(
|
||||
decimal_places=2, max_digits=5, verbose_name="Price"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='vente',
|
||||
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'),
|
||||
model_name="vente",
|
||||
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",
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -9,8 +9,8 @@ import django.db.models.deletion
|
|||
|
||||
|
||||
def add_cheque(apps, schema_editor):
|
||||
ChequePayment = apps.get_model('cotisations', 'ChequePayment')
|
||||
Payment = apps.get_model('cotisations', 'Paiement')
|
||||
ChequePayment = apps.get_model("cotisations", "ChequePayment")
|
||||
Payment = apps.get_model("cotisations", "Paiement")
|
||||
for p in Payment.objects.filter(type_paiement=1):
|
||||
cheque = ChequePayment()
|
||||
cheque.payment = p
|
||||
|
@ -18,14 +18,12 @@ def add_cheque(apps, schema_editor):
|
|||
|
||||
|
||||
def add_comnpay(apps, schema_editor):
|
||||
ComnpayPayment = apps.get_model('cotisations', 'ComnpayPayment')
|
||||
Payment = apps.get_model('cotisations', 'Paiement')
|
||||
AssoOption = apps.get_model('preferences', 'AssoOption')
|
||||
ComnpayPayment = apps.get_model("cotisations", "ComnpayPayment")
|
||||
Payment = apps.get_model("cotisations", "Paiement")
|
||||
AssoOption = apps.get_model("preferences", "AssoOption")
|
||||
options, _created = AssoOption.objects.get_or_create()
|
||||
try:
|
||||
payment = Payment.objects.get(
|
||||
moyen='Rechargement en ligne'
|
||||
)
|
||||
payment = Payment.objects.get(moyen="Rechargement en ligne")
|
||||
except Payment.DoesNotExist:
|
||||
return
|
||||
comnpay = ComnpayPayment()
|
||||
|
@ -38,11 +36,11 @@ def add_comnpay(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()
|
||||
|
||||
Payment = apps.get_model('cotisations', 'Paiement')
|
||||
BalancePayment = apps.get_model('cotisations', 'BalancePayment')
|
||||
Payment = apps.get_model("cotisations", "Paiement")
|
||||
BalancePayment = apps.get_model("cotisations", "BalancePayment")
|
||||
|
||||
try:
|
||||
solde = Payment.objects.get(moyen="solde")
|
||||
|
@ -60,73 +58,191 @@ def add_solde(apps, schema_editor):
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('preferences', '0044_remove_payment_pass'),
|
||||
('cotisations', '0029_auto_20180414_2056'),
|
||||
("preferences", "0044_remove_payment_pass"),
|
||||
("cotisations", "0029_auto_20180414_2056"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
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'},
|
||||
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",
|
||||
},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
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'},
|
||||
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",
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='paiement',
|
||||
name='available_for_everyone',
|
||||
field=models.BooleanField(default=False, verbose_name='Is available for every user'),
|
||||
model_name="paiement",
|
||||
name="available_for_everyone",
|
||||
field=models.BooleanField(
|
||||
default=False, verbose_name="Is available for every user"
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='paiement',
|
||||
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]),
|
||||
model_name="paiement",
|
||||
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],
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='article',
|
||||
name='available_for_everyone',
|
||||
field=models.BooleanField(default=False, verbose_name='Is available for every user'),
|
||||
model_name="article",
|
||||
name="available_for_everyone",
|
||||
field=models.BooleanField(
|
||||
default=False, verbose_name="Is available for every user"
|
||||
),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ChequePayment',
|
||||
name="ChequePayment",
|
||||
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),
|
||||
options={'verbose_name': 'Cheque'},
|
||||
options={"verbose_name": "Cheque"},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ComnpayPayment',
|
||||
name="ComnpayPayment",
|
||||
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')),
|
||||
('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')),
|
||||
(
|
||||
"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",
|
||||
),
|
||||
),
|
||||
(
|
||||
"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),
|
||||
options={'verbose_name': 'ComNpay'},
|
||||
options={"verbose_name": "ComNpay"},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='BalancePayment',
|
||||
name="BalancePayment",
|
||||
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')),
|
||||
('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')),
|
||||
(
|
||||
"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",
|
||||
),
|
||||
),
|
||||
(
|
||||
"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),
|
||||
options={'verbose_name': 'User Balance'},
|
||||
options={"verbose_name": "User Balance"},
|
||||
),
|
||||
migrations.RunPython(add_comnpay),
|
||||
migrations.RunPython(add_cheque),
|
||||
migrations.RunPython(add_solde),
|
||||
migrations.RemoveField(
|
||||
model_name='paiement',
|
||||
name='type_paiement',
|
||||
),
|
||||
|
||||
migrations.RemoveField(model_name="paiement", name="type_paiement"),
|
||||
]
|
||||
|
|
|
@ -7,14 +7,15 @@ from django.db import migrations, models
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0030_custom_payment'),
|
||||
]
|
||||
dependencies = [("cotisations", "0030_custom_payment")]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='comnpaypayment',
|
||||
name='production',
|
||||
field=models.BooleanField(default=True, verbose_name='Production mode enabled (production url, instead of homologation)'),
|
||||
),
|
||||
model_name="comnpaypayment",
|
||||
name="production",
|
||||
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):
|
||||
Facture = apps.get_model('cotisations', 'Facture')
|
||||
BaseInvoice = apps.get_model('cotisations', 'BaseInvoice')
|
||||
Facture = apps.get_model("cotisations", "Facture")
|
||||
BaseInvoice = apps.get_model("cotisations", "BaseInvoice")
|
||||
|
||||
for f in Facture.objects.all():
|
||||
base = BaseInvoice.objects.create(id=f.pk)
|
||||
|
@ -22,21 +22,23 @@ def reattribute_ids(apps, schema_editor):
|
|||
|
||||
|
||||
def update_rights(apps, schema_editor):
|
||||
Permission = apps.get_model('auth', 'Permission')
|
||||
Permission = apps.get_model("auth", "Permission")
|
||||
|
||||
# creates needed permissions
|
||||
app = apps.get_app_config('cotisations')
|
||||
app = apps.get_app_config("cotisations")
|
||||
app.models_module = True
|
||||
create_permissions(app)
|
||||
app.models_module = False
|
||||
|
||||
ContentType = apps.get_model("contenttypes", "ContentType")
|
||||
content_type = ContentType.objects.get_for_model(Permission)
|
||||
former, created = Permission.objects.get_or_create(codename='change_facture_pdf', content_type=content_type)
|
||||
new_1 = Permission.objects.get(codename='add_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')
|
||||
former, created = Permission.objects.get_or_create(
|
||||
codename="change_facture_pdf", content_type=content_type
|
||||
)
|
||||
new_1 = Permission.objects.get(codename="add_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():
|
||||
group.permissions.remove(former)
|
||||
group.permissions.add(new_1)
|
||||
|
@ -48,59 +50,105 @@ def update_rights(apps, schema_editor):
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0031_comnpaypayment_production'),
|
||||
]
|
||||
dependencies = [("cotisations", "0031_comnpaypayment_production")]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='BaseInvoice',
|
||||
name="BaseInvoice",
|
||||
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(
|
||||
name='CustomInvoice',
|
||||
name="CustomInvoice",
|
||||
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')),
|
||||
('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')),
|
||||
(
|
||||
"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"),
|
||||
),
|
||||
(
|
||||
"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',),
|
||||
options={'permissions': (('view_custominvoice', 'Can view a custom invoice'),)},
|
||||
bases=("cotisations.baseinvoice",),
|
||||
options={
|
||||
"permissions": (("view_custominvoice", "Can view a custom invoice"),)
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='facture',
|
||||
name='baseinvoice_ptr',
|
||||
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='cotisations.BaseInvoice', null=True),
|
||||
model_name="facture",
|
||||
name="baseinvoice_ptr",
|
||||
field=models.OneToOneField(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="cotisations.BaseInvoice",
|
||||
null=True,
|
||||
),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.RunPython(reattribute_ids),
|
||||
migrations.AlterField(
|
||||
model_name='vente',
|
||||
name='facture',
|
||||
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',
|
||||
model_name="vente",
|
||||
name="facture",
|
||||
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.AlterField(
|
||||
model_name='facture',
|
||||
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'),
|
||||
model_name="facture",
|
||||
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",
|
||||
),
|
||||
),
|
||||
migrations.RunPython(update_rights),
|
||||
migrations.AlterModelOptions(
|
||||
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'},
|
||||
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",
|
||||
},
|
||||
),
|
||||
]
|
||||
|
|
|
@ -11,171 +11,294 @@ import re2o.aes_field
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0032_custom_invoice'),
|
||||
]
|
||||
dependencies = [("cotisations", "0032_custom_invoice")]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
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'},
|
||||
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",
|
||||
},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='balancepayment',
|
||||
options={'verbose_name': 'user balance'},
|
||||
name="balancepayment", options={"verbose_name": "user balance"}
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='banque',
|
||||
options={'permissions': (('view_banque', 'Can view a bank object'),), 'verbose_name': 'bank', 'verbose_name_plural': 'banks'},
|
||||
name="banque",
|
||||
options={
|
||||
"permissions": (("view_banque", "Can view a bank object"),),
|
||||
"verbose_name": "bank",
|
||||
"verbose_name_plural": "banks",
|
||||
},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
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'},
|
||||
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",
|
||||
},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='custominvoice',
|
||||
options={'permissions': (('view_custominvoice', 'Can view a custom invoice object'),)},
|
||||
name="custominvoice",
|
||||
options={
|
||||
"permissions": (
|
||||
("view_custominvoice", "Can view a custom invoice object"),
|
||||
)
|
||||
},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
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'},
|
||||
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",
|
||||
},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
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'},
|
||||
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",
|
||||
},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
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'},
|
||||
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",
|
||||
},
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='article',
|
||||
name='available_for_everyone',
|
||||
field=models.BooleanField(default=False, verbose_name='is available for every user'),
|
||||
model_name="article",
|
||||
name="available_for_everyone",
|
||||
field=models.BooleanField(
|
||||
default=False, verbose_name="is available for every user"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='article',
|
||||
name='duration',
|
||||
field=models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(0)], verbose_name='duration (in months)'),
|
||||
model_name="article",
|
||||
name="duration",
|
||||
field=models.PositiveIntegerField(
|
||||
blank=True,
|
||||
null=True,
|
||||
validators=[django.core.validators.MinValueValidator(0)],
|
||||
verbose_name="duration (in months)",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='article',
|
||||
name='name',
|
||||
field=models.CharField(max_length=255, verbose_name='designation'),
|
||||
model_name="article",
|
||||
name="name",
|
||||
field=models.CharField(max_length=255, verbose_name="designation"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='article',
|
||||
name='prix',
|
||||
field=models.DecimalField(decimal_places=2, max_digits=5, verbose_name='unit price'),
|
||||
model_name="article",
|
||||
name="prix",
|
||||
field=models.DecimalField(
|
||||
decimal_places=2, max_digits=5, verbose_name="unit price"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='article',
|
||||
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'),
|
||||
model_name="article",
|
||||
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",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='article',
|
||||
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'),
|
||||
model_name="article",
|
||||
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",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='banque',
|
||||
name='name',
|
||||
field=models.CharField(max_length=255),
|
||||
model_name="banque", name="name", field=models.CharField(max_length=255)
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='comnpaypayment',
|
||||
name='payment_credential',
|
||||
field=models.CharField(blank=True, default='', max_length=255, verbose_name='ComNpay VAT Number'),
|
||||
model_name="comnpaypayment",
|
||||
name="payment_credential",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
default="",
|
||||
max_length=255,
|
||||
verbose_name="ComNpay VAT Number",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='comnpaypayment',
|
||||
name='payment_pass',
|
||||
field=re2o.aes_field.AESEncryptedField(blank=True, max_length=255, null=True, verbose_name='ComNpay secret key'),
|
||||
model_name="comnpaypayment",
|
||||
name="payment_pass",
|
||||
field=re2o.aes_field.AESEncryptedField(
|
||||
blank=True, max_length=255, null=True, verbose_name="ComNpay secret key"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='comnpaypayment',
|
||||
name='production',
|
||||
field=models.BooleanField(default=True, verbose_name='Production mode enabled (production URL, instead of homologation)'),
|
||||
model_name="comnpaypayment",
|
||||
name="production",
|
||||
field=models.BooleanField(
|
||||
default=True,
|
||||
verbose_name="Production mode enabled (production URL, instead of homologation)",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cotisation',
|
||||
name='date_end',
|
||||
field=models.DateTimeField(verbose_name='end date'),
|
||||
model_name="cotisation",
|
||||
name="date_end",
|
||||
field=models.DateTimeField(verbose_name="end date"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cotisation',
|
||||
name='date_start',
|
||||
field=models.DateTimeField(verbose_name='start date'),
|
||||
model_name="cotisation",
|
||||
name="date_start",
|
||||
field=models.DateTimeField(verbose_name="start date"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='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'),
|
||||
model_name="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",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cotisation',
|
||||
name='vente',
|
||||
field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to='cotisations.Vente', verbose_name='purchase'),
|
||||
model_name="cotisation",
|
||||
name="vente",
|
||||
field=models.OneToOneField(
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="cotisations.Vente",
|
||||
verbose_name="purchase",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='facture',
|
||||
name='cheque',
|
||||
field=models.CharField(blank=True, max_length=255, verbose_name='cheque number'),
|
||||
model_name="facture",
|
||||
name="cheque",
|
||||
field=models.CharField(
|
||||
blank=True, max_length=255, verbose_name="cheque number"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='facture',
|
||||
name='control',
|
||||
field=models.BooleanField(default=False, verbose_name='controlled'),
|
||||
model_name="facture",
|
||||
name="control",
|
||||
field=models.BooleanField(default=False, verbose_name="controlled"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='facture',
|
||||
name='valid',
|
||||
field=models.BooleanField(default=True, verbose_name='validated'),
|
||||
model_name="facture",
|
||||
name="valid",
|
||||
field=models.BooleanField(default=True, verbose_name="validated"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='paiement',
|
||||
name='available_for_everyone',
|
||||
field=models.BooleanField(default=False, verbose_name='is available for every user'),
|
||||
model_name="paiement",
|
||||
name="available_for_everyone",
|
||||
field=models.BooleanField(
|
||||
default=False, verbose_name="is available for every user"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='paiement',
|
||||
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'),
|
||||
model_name="paiement",
|
||||
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",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='paiement',
|
||||
name='moyen',
|
||||
field=models.CharField(max_length=255, verbose_name='method'),
|
||||
model_name="paiement",
|
||||
name="moyen",
|
||||
field=models.CharField(max_length=255, verbose_name="method"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='vente',
|
||||
name='duration',
|
||||
field=models.PositiveIntegerField(blank=True, null=True, verbose_name='duration (in months)'),
|
||||
model_name="vente",
|
||||
name="duration",
|
||||
field=models.PositiveIntegerField(
|
||||
blank=True, null=True, verbose_name="duration (in months)"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='vente',
|
||||
name='facture',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cotisations.BaseInvoice', verbose_name='invoice'),
|
||||
model_name="vente",
|
||||
name="facture",
|
||||
field=models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="cotisations.BaseInvoice",
|
||||
verbose_name="invoice",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='vente',
|
||||
name='name',
|
||||
field=models.CharField(max_length=255, verbose_name='article'),
|
||||
model_name="vente",
|
||||
name="name",
|
||||
field=models.CharField(max_length=255, verbose_name="article"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='vente',
|
||||
name='number',
|
||||
field=models.IntegerField(validators=[django.core.validators.MinValueValidator(1)], verbose_name='amount'),
|
||||
model_name="vente",
|
||||
name="number",
|
||||
field=models.IntegerField(
|
||||
validators=[django.core.validators.MinValueValidator(1)],
|
||||
verbose_name="amount",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='vente',
|
||||
name='prix',
|
||||
field=models.DecimalField(decimal_places=2, max_digits=5, verbose_name='price'),
|
||||
model_name="vente",
|
||||
name="prix",
|
||||
field=models.DecimalField(
|
||||
decimal_places=2, max_digits=5, verbose_name="price"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='vente',
|
||||
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'),
|
||||
model_name="vente",
|
||||
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",
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -7,14 +7,12 @@ from django.db import migrations, models
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0033_auto_20180818_1319'),
|
||||
]
|
||||
dependencies = [("cotisations", "0033_auto_20180818_1319")]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='facture',
|
||||
name='valid',
|
||||
field=models.BooleanField(default=False, verbose_name='validated'),
|
||||
),
|
||||
model_name="facture",
|
||||
name="valid",
|
||||
field=models.BooleanField(default=False, verbose_name="validated"),
|
||||
)
|
||||
]
|
||||
|
|
|
@ -9,23 +9,35 @@ import django.db.models.deletion
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0034_auto_20180831_1532'),
|
||||
]
|
||||
dependencies = [("cotisations", "0034_auto_20180831_1532")]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='NotePayment',
|
||||
name="NotePayment",
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('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')),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("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',
|
||||
},
|
||||
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):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0035_notepayment'),
|
||||
]
|
||||
dependencies = [("cotisations", "0035_notepayment")]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='custominvoice',
|
||||
name='remark',
|
||||
field=models.TextField(blank=True, null=True, verbose_name='Remark'),
|
||||
),
|
||||
model_name="custominvoice",
|
||||
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):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0036_custominvoice_remark'),
|
||||
]
|
||||
dependencies = [("cotisations", "0036_custominvoice_remark")]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='CostEstimate',
|
||||
name="CostEstimate",
|
||||
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')),
|
||||
('final_invoice', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='origin_cost_estimate', to='cotisations.CustomInvoice')),
|
||||
(
|
||||
"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")),
|
||||
(
|
||||
"final_invoice",
|
||||
models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="origin_cost_estimate",
|
||||
to="cotisations.CustomInvoice",
|
||||
),
|
||||
),
|
||||
],
|
||||
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):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0037_costestimate'),
|
||||
]
|
||||
dependencies = [("cotisations", "0037_costestimate")]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='costestimate',
|
||||
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'),
|
||||
model_name="costestimate",
|
||||
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",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='costestimate',
|
||||
name='validity',
|
||||
field=models.DurationField(help_text='DD HH:MM:SS', verbose_name='Period of validity'),
|
||||
model_name="costestimate",
|
||||
name="validity",
|
||||
field=models.DurationField(
|
||||
help_text="DD HH:MM:SS", verbose_name="Period of validity"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='custominvoice',
|
||||
name='paid',
|
||||
field=models.BooleanField(default=False, verbose_name='Paid'),
|
||||
model_name="custominvoice",
|
||||
name="paid",
|
||||
field=models.BooleanField(default=False, verbose_name="Paid"),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -9,20 +9,32 @@ import django.db.models.deletion
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0038_auto_20181231_1657'),
|
||||
]
|
||||
dependencies = [("cotisations", "0038_auto_20181231_1657")]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='FreePayment',
|
||||
name="FreePayment",
|
||||
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",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Free payment',
|
||||
},
|
||||
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):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0039_freepayment'),
|
||||
]
|
||||
dependencies = [("cotisations", "0039_freepayment")]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='article',
|
||||
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)'),
|
||||
model_name="article",
|
||||
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)",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='vente',
|
||||
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)'),
|
||||
model_name="vente",
|
||||
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)",
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -8,34 +8,57 @@ import django.db.models.deletion
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0040_auto_20191002_2335'),
|
||||
]
|
||||
dependencies = [("cotisations", "0040_auto_20191002_2335")]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='balancepayment',
|
||||
name='payment',
|
||||
field=models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='payment_method_balance', to='cotisations.Paiement'),
|
||||
model_name="balancepayment",
|
||||
name="payment",
|
||||
field=models.OneToOneField(
|
||||
editable=False,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="payment_method_balance",
|
||||
to="cotisations.Paiement",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='chequepayment',
|
||||
name='payment',
|
||||
field=models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='payment_method_cheque', to='cotisations.Paiement'),
|
||||
model_name="chequepayment",
|
||||
name="payment",
|
||||
field=models.OneToOneField(
|
||||
editable=False,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="payment_method_cheque",
|
||||
to="cotisations.Paiement",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='comnpaypayment',
|
||||
name='payment',
|
||||
field=models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='payment_method_comnpay', to='cotisations.Paiement'),
|
||||
model_name="comnpaypayment",
|
||||
name="payment",
|
||||
field=models.OneToOneField(
|
||||
editable=False,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="payment_method_comnpay",
|
||||
to="cotisations.Paiement",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='freepayment',
|
||||
name='payment',
|
||||
field=models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='payment_method_free', to='cotisations.Paiement'),
|
||||
model_name="freepayment",
|
||||
name="payment",
|
||||
field=models.OneToOneField(
|
||||
editable=False,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="payment_method_free",
|
||||
to="cotisations.Paiement",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='notepayment',
|
||||
name='payment',
|
||||
field=models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='payment_method_note', to='cotisations.Paiement'),
|
||||
model_name="notepayment",
|
||||
name="payment",
|
||||
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
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 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
|
||||
|
||||
PAYMENT_METHODS = [
|
||||
comnpay,
|
||||
cheque,
|
||||
balance,
|
||||
note_kfet,
|
||||
free
|
||||
]
|
||||
PAYMENT_METHODS = [comnpay, cheque, balance, note_kfet, free]
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
This module contains a method to pay online using user balance.
|
||||
"""
|
||||
from . import models
|
||||
|
||||
NAME = "BALANCE"
|
||||
|
||||
PaymentMethod = models.BalancePayment
|
||||
|
|
|
@ -40,15 +40,16 @@ class BalancePayment(PaymentMethodMixin, models.Model):
|
|||
payment = models.OneToOneField(
|
||||
Paiement,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='payment_method_balance',
|
||||
editable=False
|
||||
related_name="payment_method_balance",
|
||||
editable=False,
|
||||
)
|
||||
minimum_balance = models.DecimalField(
|
||||
verbose_name=_("Minimum balance"),
|
||||
help_text=_("The minimal amount of money allowed for the balance"
|
||||
" at the end of a payment. You can specify negative "
|
||||
"amount."
|
||||
),
|
||||
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,
|
||||
decimal_places=2,
|
||||
default=0,
|
||||
|
@ -63,8 +64,7 @@ class BalancePayment(PaymentMethodMixin, models.Model):
|
|||
null=True,
|
||||
)
|
||||
credit_balance_allowed = models.BooleanField(
|
||||
verbose_name=_("Allow user to credit their balance"),
|
||||
default=False,
|
||||
verbose_name=_("Allow user to credit their balance"), default=False
|
||||
)
|
||||
|
||||
def end_payment(self, invoice, request):
|
||||
|
@ -74,27 +74,17 @@ class BalancePayment(PaymentMethodMixin, models.Model):
|
|||
user = invoice.user
|
||||
total_price = invoice.prix_total()
|
||||
if user.solde - total_price < self.minimum_balance:
|
||||
messages.error(
|
||||
request,
|
||||
_("Your balance is too low for this operation.")
|
||||
)
|
||||
return redirect(reverse(
|
||||
'users:profil',
|
||||
kwargs={'userid': user.id}
|
||||
))
|
||||
return invoice.paiement.end_payment(
|
||||
invoice,
|
||||
request,
|
||||
use_payment_method=False
|
||||
)
|
||||
messages.error(request, _("Your balance is too low for this operation."))
|
||||
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):
|
||||
"""Checks that there is not already a balance payment method."""
|
||||
p = Paiement.objects.filter(is_balance=True)
|
||||
if len(p) > 0:
|
||||
form.add_error(
|
||||
'payment_method',
|
||||
_("There is already a payment method for user balance.")
|
||||
"payment_method",
|
||||
_("There is already a payment method for user balance."),
|
||||
)
|
||||
|
||||
def alter_payment(self, payment):
|
||||
|
@ -107,12 +97,11 @@ class BalancePayment(PaymentMethodMixin, models.Model):
|
|||
"""
|
||||
return (
|
||||
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):
|
||||
return (
|
||||
len(Paiement.find_allowed_payments(user_request)
|
||||
.exclude(is_balance=True)) > 0
|
||||
len(Paiement.find_allowed_payments(user_request).exclude(is_balance=True))
|
||||
> 0
|
||||
) and self.credit_balance_allowed
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
This module contains a method to pay online using cheque.
|
||||
"""
|
||||
from . import models, urls, views
|
||||
|
||||
NAME = "CHEQUE"
|
||||
|
||||
PaymentMethod = models.ChequePayment
|
||||
|
|
|
@ -26,6 +26,7 @@ from cotisations.models import Facture as Invoice
|
|||
|
||||
class InvoiceForm(FormRevMixin, forms.ModelForm):
|
||||
"""A simple form to get the bank a the cheque number."""
|
||||
|
||||
class Meta:
|
||||
model = Invoice
|
||||
fields = ['banque', 'cheque']
|
||||
fields = ["banque", "cheque"]
|
||||
|
|
|
@ -38,16 +38,14 @@ class ChequePayment(PaymentMethodMixin, models.Model):
|
|||
payment = models.OneToOneField(
|
||||
Paiement,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='payment_method_cheque',
|
||||
editable=False
|
||||
related_name="payment_method_cheque",
|
||||
editable=False,
|
||||
)
|
||||
|
||||
def end_payment(self, invoice, request):
|
||||
"""Invalidates the invoice then redirect the user towards a view asking
|
||||
for informations to add to the invoice before validating it.
|
||||
"""
|
||||
return redirect(reverse(
|
||||
'cotisations:cheque:validate',
|
||||
kwargs={'invoice_pk': invoice.pk}
|
||||
))
|
||||
|
||||
return redirect(
|
||||
reverse("cotisations:cheque:validate", kwargs={"invoice_pk": invoice.pk})
|
||||
)
|
||||
|
|
|
@ -21,10 +21,4 @@
|
|||
from django.conf.urls import url
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
url(
|
||||
r'^validate/(?P<invoice_pk>[0-9]+)$',
|
||||
views.cheque,
|
||||
name='validate'
|
||||
)
|
||||
]
|
||||
urlpatterns = [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)
|
||||
payment_method = find_payment_method(invoice.paiement)
|
||||
if invoice.valid or not isinstance(payment_method, ChequePayment):
|
||||
messages.error(
|
||||
request,
|
||||
_("You can't pay this invoice with a cheque.")
|
||||
)
|
||||
return redirect(reverse(
|
||||
'users:profil',
|
||||
kwargs={'userid': request.user.pk}
|
||||
))
|
||||
messages.error(request, _("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)
|
||||
if form.is_valid():
|
||||
form.instance.valid = True
|
||||
form.save()
|
||||
return form.instance.paiement.end_payment(
|
||||
form.instance,
|
||||
request,
|
||||
use_payment_method=False
|
||||
form.instance, request, use_payment_method=False
|
||||
)
|
||||
return render(
|
||||
request,
|
||||
'cotisations/payment.html',
|
||||
{
|
||||
'form': form,
|
||||
'amount': invoice.prix_total()
|
||||
}
|
||||
"cotisations/payment.html",
|
||||
{"form": form, "amount": invoice.prix_total()},
|
||||
)
|
||||
|
||||
|
|
|
@ -22,5 +22,6 @@
|
|||
This module contains a method to pay online using comnpay.
|
||||
"""
|
||||
from . import models, urls, views
|
||||
|
||||
NAME = "COMNPAY"
|
||||
PaymentMethod = models.ComnpayPayment
|
||||
|
|
|
@ -10,13 +10,21 @@ import hashlib
|
|||
from collections import OrderedDict
|
||||
|
||||
|
||||
class Transaction():
|
||||
class Transaction:
|
||||
""" The class representing a transaction with all the functions
|
||||
used during the negociation
|
||||
"""
|
||||
|
||||
def __init__(self, vad_number="", secret_key="", urlRetourOK="",
|
||||
urlRetourNOK="", urlIPN="", source="", typeTr="D"):
|
||||
def __init__(
|
||||
self,
|
||||
vad_number="",
|
||||
secret_key="",
|
||||
urlRetourOK="",
|
||||
urlRetourNOK="",
|
||||
urlIPN="",
|
||||
source="",
|
||||
typeTr="D",
|
||||
):
|
||||
self.vad_number = vad_number
|
||||
self.secret_key = secret_key
|
||||
self.urlRetourOK = urlRetourOK
|
||||
|
@ -26,8 +34,7 @@ class Transaction():
|
|||
self.typeTr = typeTr
|
||||
self.idTransaction = ""
|
||||
|
||||
def buildSecretHTML(self, produit="Produit", montant="0.00",
|
||||
idTransaction=""):
|
||||
def buildSecretHTML(self, produit="Produit", montant="0.00", idTransaction=""):
|
||||
""" Build an HTML hidden form with the different parameters for the
|
||||
transaction
|
||||
"""
|
||||
|
@ -43,30 +50,26 @@ class Transaction():
|
|||
idTPE=self.vad_number,
|
||||
idTransaction=self.idTransaction,
|
||||
devise="EUR",
|
||||
lang='fr',
|
||||
lang="fr",
|
||||
nom_produit=produit,
|
||||
source=self.source,
|
||||
urlRetourOK=self.urlRetourOK,
|
||||
urlRetourNOK=self.urlRetourNOK,
|
||||
typeTr=str(self.typeTr)
|
||||
typeTr=str(self.typeTr),
|
||||
)
|
||||
|
||||
if self.urlIPN != "":
|
||||
array_tpe['urlIPN'] = self.urlIPN
|
||||
array_tpe["urlIPN"] = self.urlIPN
|
||||
|
||||
array_tpe['key'] = self.secret_key
|
||||
strWithKey = base64.b64encode(bytes(
|
||||
'|'.join(array_tpe.values()),
|
||||
'utf-8'
|
||||
))
|
||||
array_tpe["key"] = self.secret_key
|
||||
strWithKey = base64.b64encode(bytes("|".join(array_tpe.values()), "utf-8"))
|
||||
del array_tpe["key"]
|
||||
array_tpe['sec'] = hashlib.sha512(strWithKey).hexdigest()
|
||||
array_tpe["sec"] = hashlib.sha512(strWithKey).hexdigest()
|
||||
|
||||
ret = ""
|
||||
for key in array_tpe:
|
||||
ret += '<input type="hidden" name="{k}" value="{v}"/>'.format(
|
||||
k=key,
|
||||
v=array_tpe[key]
|
||||
k=key, v=array_tpe[key]
|
||||
)
|
||||
|
||||
return ret
|
||||
|
@ -75,12 +78,13 @@ class Transaction():
|
|||
def validSec(values, secret_key):
|
||||
""" Check if the secret value is correct """
|
||||
if "sec" in values:
|
||||
sec = values['sec']
|
||||
sec = values["sec"]
|
||||
del values["sec"]
|
||||
strWithKey = hashlib.sha512(base64.b64encode(bytes(
|
||||
'|'.join(values.values()) + "|" + secret_key,
|
||||
'utf-8'
|
||||
))).hexdigest()
|
||||
strWithKey = hashlib.sha512(
|
||||
base64.b64encode(
|
||||
bytes("|".join(values.values()) + "|" + secret_key, "utf-8")
|
||||
)
|
||||
).hexdigest()
|
||||
return strWithKey.upper() == sec.upper()
|
||||
else:
|
||||
return False
|
||||
|
|
|
@ -41,39 +41,36 @@ class ComnpayPayment(PaymentMethodMixin, models.Model):
|
|||
payment = models.OneToOneField(
|
||||
Paiement,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='payment_method_comnpay',
|
||||
editable=False
|
||||
related_name="payment_method_comnpay",
|
||||
editable=False,
|
||||
)
|
||||
payment_credential = models.CharField(
|
||||
max_length=255,
|
||||
default='',
|
||||
blank=True,
|
||||
verbose_name=_("ComNpay VAT Number"),
|
||||
max_length=255, default="", blank=True, verbose_name=_("ComNpay VAT Number")
|
||||
)
|
||||
payment_pass = AESEncryptedField(
|
||||
max_length=255,
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name=_("ComNpay secret key"),
|
||||
max_length=255, null=True, blank=True, verbose_name=_("ComNpay secret key")
|
||||
)
|
||||
minimum_payment = models.DecimalField(
|
||||
verbose_name=_("Minimum payment"),
|
||||
help_text=_("The minimal amount of money you have to use when paying"
|
||||
" with ComNpay"),
|
||||
help_text=_(
|
||||
"The minimal amount of money you have to use when paying" " with ComNpay"
|
||||
),
|
||||
max_digits=5,
|
||||
decimal_places=2,
|
||||
default=1,
|
||||
)
|
||||
production = models.BooleanField(
|
||||
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):
|
||||
if self.production:
|
||||
return 'https://secure.comnpay.com'
|
||||
return "https://secure.comnpay.com"
|
||||
else:
|
||||
return 'https://secure.homologation.comnpay.com'
|
||||
return "https://secure.homologation.comnpay.com"
|
||||
|
||||
def end_payment(self, invoice, request):
|
||||
"""
|
||||
|
@ -85,32 +82,36 @@ class ComnpayPayment(PaymentMethodMixin, models.Model):
|
|||
p = Transaction(
|
||||
str(self.payment_credential),
|
||||
str(self.payment_pass),
|
||||
'https://' + host + reverse(
|
||||
'cotisations:comnpay:accept_payment',
|
||||
kwargs={'factureid': invoice.id}
|
||||
"https://"
|
||||
+ host
|
||||
+ reverse(
|
||||
"cotisations:comnpay:accept_payment", kwargs={"factureid": invoice.id}
|
||||
),
|
||||
'https://' + host + reverse('cotisations:comnpay:refuse_payment'),
|
||||
'https://' + host + reverse('cotisations:comnpay:ipn'),
|
||||
"https://" + host + reverse("cotisations:comnpay:refuse_payment"),
|
||||
"https://" + host + reverse("cotisations:comnpay:ipn"),
|
||||
"",
|
||||
"D"
|
||||
"D",
|
||||
)
|
||||
|
||||
r = {
|
||||
'action': self.return_url_comnpay(),
|
||||
'method': 'POST',
|
||||
'content': p.buildSecretHTML(
|
||||
_("Pay invoice number ")+str(invoice.id),
|
||||
"action": self.return_url_comnpay(),
|
||||
"method": "POST",
|
||||
"content": p.buildSecretHTML(
|
||||
_("Pay invoice number ") + str(invoice.id),
|
||||
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):
|
||||
"""Checks that the price meets the requirement to be paid with ComNpay.
|
||||
"""
|
||||
return ((price >= self.minimum_payment),
|
||||
_("In order to pay your invoice with ComNpay, the price must"
|
||||
" be greater than {} €.").format(self.minimum_payment))
|
||||
|
||||
return (
|
||||
(price >= 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
|
||||
|
||||
urlpatterns = [
|
||||
url(
|
||||
r'^accept/(?P<factureid>[0-9]+)$',
|
||||
views.accept_payment,
|
||||
name='accept_payment'
|
||||
),
|
||||
url(
|
||||
r'^refuse/$',
|
||||
views.refuse_payment,
|
||||
name='refuse_payment'
|
||||
),
|
||||
url(
|
||||
r'^ipn/$',
|
||||
views.ipn,
|
||||
name='ipn'
|
||||
),
|
||||
url(r"^accept/(?P<factureid>[0-9]+)$", views.accept_payment, 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:
|
||||
messages.success(
|
||||
request,
|
||||
_("The payment of %(amount)s € was accepted.") % {
|
||||
'amount': invoice.prix_total()
|
||||
}
|
||||
_("The payment of %(amount)s € was accepted.")
|
||||
% {"amount": invoice.prix_total()},
|
||||
)
|
||||
# In case a cotisation was bought, inform the user, the
|
||||
# cotisation time has been extended too
|
||||
if any(purchase.type_cotisation
|
||||
for purchase in invoice.vente_set.all()):
|
||||
if any(purchase.type_cotisation for purchase in invoice.vente_set.all()):
|
||||
messages.success(
|
||||
request,
|
||||
_("The subscription of %(member_name)s was extended to"
|
||||
" %(end_date)s.") % {
|
||||
'member_name': invoice.user.pseudo,
|
||||
'end_date': invoice.user.end_adhesion()
|
||||
}
|
||||
_(
|
||||
"The subscription of %(member_name)s was extended to"
|
||||
" %(end_date)s."
|
||||
)
|
||||
% {
|
||||
"member_name": invoice.user.pseudo,
|
||||
"end_date": invoice.user.end_adhesion(),
|
||||
},
|
||||
)
|
||||
return redirect(reverse(
|
||||
'users:profil',
|
||||
kwargs={'userid': invoice.user.id}
|
||||
))
|
||||
return redirect(reverse("users:profil", kwargs={"userid": invoice.user.id}))
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
|
@ -79,14 +77,8 @@ def refuse_payment(request):
|
|||
The view where the user is redirected when a comnpay payment has been
|
||||
refused.
|
||||
"""
|
||||
messages.error(
|
||||
request,
|
||||
_("The payment was refused.")
|
||||
)
|
||||
return redirect(reverse(
|
||||
'users:profil',
|
||||
kwargs={'userid': request.user.id}
|
||||
))
|
||||
messages.error(request, _("The payment was refused."))
|
||||
return redirect(reverse("users:profil", kwargs={"userid": request.user.id}))
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
|
@ -97,27 +89,26 @@ def ipn(request):
|
|||
Comnpay with 400 response if not or with a 200 response if yes.
|
||||
"""
|
||||
p = Transaction()
|
||||
order = ('idTpe', 'idTransaction', 'montant', 'result', 'sec', )
|
||||
order = ("idTpe", "idTransaction", "montant", "result", "sec")
|
||||
try:
|
||||
data = OrderedDict([(f, request.POST[f]) for f in order])
|
||||
except MultiValueDictKeyError:
|
||||
return HttpResponseBadRequest("HTTP/1.1 400 Bad Request")
|
||||
|
||||
idTransaction = request.POST['idTransaction']
|
||||
idTransaction = request.POST["idTransaction"]
|
||||
try:
|
||||
factureid = int(idTransaction)
|
||||
except ValueError:
|
||||
return HttpResponseBadRequest("HTTP/1.1 400 Bad Request")
|
||||
|
||||
facture = get_object_or_404(Facture, id=factureid)
|
||||
payment_method = get_object_or_404(
|
||||
ComnpayPayment, payment=facture.paiement)
|
||||
payment_method = get_object_or_404(ComnpayPayment, payment=facture.paiement)
|
||||
|
||||
if not p.validSec(data, payment_method.payment_pass):
|
||||
return HttpResponseBadRequest("HTTP/1.1 400 Bad Request")
|
||||
|
||||
result = True if (request.POST['result'] == 'OK') else False
|
||||
idTpe = request.POST['idTpe']
|
||||
result = True if (request.POST["result"] == "OK") else False
|
||||
idTpe = request.POST["idTpe"]
|
||||
|
||||
# Checking that the payment is actually for us.
|
||||
if not idTpe == payment_method.payment_credential:
|
||||
|
@ -136,4 +127,3 @@ def ipn(request):
|
|||
# Everything worked we send a reponse to Comnpay indicating that
|
||||
# it's ok for them to proceed
|
||||
return HttpResponse("HTTP/1.0 200 OK")
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ from django.utils.translation import ugettext_lazy as _
|
|||
from . import PAYMENT_METHODS
|
||||
from cotisations.utils import find_payment_method
|
||||
|
||||
|
||||
def payment_method_factory(payment, *args, creation=True, **kwargs):
|
||||
"""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:
|
||||
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:
|
||||
return forms.modelform_factory(type(payment_method), fields='__all__')(
|
||||
*args,
|
||||
instance=payment_method,
|
||||
**kwargs
|
||||
return forms.modelform_factory(type(payment_method), fields="__all__")(
|
||||
*args, instance=payment_method, **kwargs
|
||||
)
|
||||
elif creation:
|
||||
return PaymentMethodForm(*args, **kwargs)
|
||||
|
@ -58,23 +57,24 @@ class PaymentMethodForm(forms.Form):
|
|||
|
||||
payment_method = forms.ChoiceField(
|
||||
label=_("Special payment method"),
|
||||
help_text=_("Warning: you will not be able to change the payment "
|
||||
"method later. But you will be allowed to edit the other "
|
||||
"options."
|
||||
help_text=_(
|
||||
"Warning: you will not be able to change the payment "
|
||||
"method later. But you will be allowed to edit the other "
|
||||
"options."
|
||||
),
|
||||
required=False
|
||||
required=False,
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(PaymentMethodForm, self).__init__(*args, **kwargs)
|
||||
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.insert(0, ('', _('no')))
|
||||
self.fields['payment_method'].widget.attrs = {
|
||||
'id': 'paymentMethodSelect'
|
||||
}
|
||||
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.insert(0, ("", _("no")))
|
||||
self.fields["payment_method"].widget.attrs = {"id": "paymentMethodSelect"}
|
||||
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
|
||||
]
|
||||
|
||||
|
@ -84,29 +84,29 @@ class PaymentMethodForm(forms.Form):
|
|||
found. Tries to call `payment_method.valid_form` if it exists.
|
||||
"""
|
||||
super(PaymentMethodForm, self).clean()
|
||||
choice = self.cleaned_data['payment_method']
|
||||
if choice=='':
|
||||
choice = self.cleaned_data["payment_method"]
|
||||
if choice == "":
|
||||
return
|
||||
choice = int(choice)
|
||||
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)
|
||||
if hasattr(self.payment_method, 'valid_form'):
|
||||
if hasattr(self.payment_method, "valid_form"):
|
||||
self.payment_method.valid_form(self)
|
||||
return self.cleaned_data
|
||||
|
||||
|
||||
|
||||
def save(self, payment, *args, **kwargs):
|
||||
"""Saves the payment method.
|
||||
|
||||
Tries to call `payment_method.alter_payment` if it exists.
|
||||
"""
|
||||
commit = kwargs.pop('commit', True)
|
||||
if not hasattr(self, 'payment_method'):
|
||||
commit = kwargs.pop("commit", True)
|
||||
if not hasattr(self, "payment_method"):
|
||||
return None
|
||||
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)
|
||||
if commit:
|
||||
payment.save()
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
This module contains a method to pay online using user balance.
|
||||
"""
|
||||
from . import models
|
||||
|
||||
NAME = "FREE"
|
||||
|
||||
PaymentMethod = models.FreePayment
|
||||
|
|
|
@ -38,24 +38,17 @@ class FreePayment(PaymentMethodMixin, models.Model):
|
|||
payment = models.OneToOneField(
|
||||
Paiement,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='payment_method_free',
|
||||
editable=False
|
||||
related_name="payment_method_free",
|
||||
editable=False,
|
||||
)
|
||||
|
||||
def end_payment(self, invoice, request):
|
||||
"""Ends the payment normally.
|
||||
"""
|
||||
return invoice.paiement.end_payment(
|
||||
invoice,
|
||||
request,
|
||||
use_payment_method=False
|
||||
)
|
||||
return invoice.paiement.end_payment(invoice, request, use_payment_method=False)
|
||||
|
||||
def check_price(self, price, user, *args, **kwargs):
|
||||
"""Checks that the price meets the requirement to be paid with user
|
||||
balance.
|
||||
"""
|
||||
return (
|
||||
price == 0,
|
||||
_("You cannot validate this invoice for free.")
|
||||
)
|
||||
return (price == 0, _("You cannot validate this invoice for free."))
|
||||
|
|
|
@ -29,5 +29,4 @@ class PaymentMethodMixin:
|
|||
|
||||
Must return a HttpResponse-like object.
|
||||
"""
|
||||
return self.payment.end_payment(
|
||||
invoice, request, use_payment_method=False)
|
||||
return self.payment.end_payment(invoice, request, use_payment_method=False)
|
||||
|
|
|
@ -22,5 +22,6 @@
|
|||
This module contains a method to pay online using comnpay.
|
||||
"""
|
||||
from . import models, urls
|
||||
|
||||
NAME = "NOTE"
|
||||
PaymentMethod = models.NotePayment
|
||||
|
|
|
@ -24,15 +24,11 @@ from django.utils.translation import ugettext_lazy as _
|
|||
|
||||
from cotisations.utils import find_payment_method
|
||||
|
||||
|
||||
class NoteCredentialForm(forms.Form):
|
||||
"""A special form to get credential to connect to a NoteKfet2015 server throught his API
|
||||
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)
|
||||
|
|
|
@ -41,25 +41,17 @@ class NotePayment(PaymentMethodMixin, models.Model):
|
|||
|
||||
payment = models.OneToOneField(
|
||||
Paiement,
|
||||
on_delete = models.CASCADE,
|
||||
related_name = 'payment_method_note',
|
||||
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
|
||||
on_delete=models.CASCADE,
|
||||
related_name="payment_method_note",
|
||||
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)
|
||||
|
||||
def end_payment(self, invoice, request):
|
||||
return redirect(reverse(
|
||||
'cotisations:note_kfet:note_payment',
|
||||
kwargs={'factureid': invoice.id}
|
||||
))
|
||||
return redirect(
|
||||
reverse(
|
||||
"cotisations:note_kfet:note_payment", kwargs={"factureid": invoice.id}
|
||||
)
|
||||
)
|
||||
|
|
|
@ -12,13 +12,14 @@ import traceback
|
|||
|
||||
|
||||
def get_response(socket):
|
||||
length_str = b''
|
||||
length_str = b""
|
||||
char = socket.recv(1)
|
||||
while char != b'\n':
|
||||
while char != b"\n":
|
||||
length_str += char
|
||||
char = socket.recv(1)
|
||||
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):
|
||||
sock = socket.socket()
|
||||
|
@ -35,7 +36,8 @@ def connect(server, port):
|
|||
return (False, sock, "Serveur indisponible")
|
||||
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)
|
||||
if not result:
|
||||
return (False, None, err)
|
||||
|
@ -43,7 +45,7 @@ def login(server, port, username, password, masque = [[], [], True]):
|
|||
commande = ["login", [username, password, "bdd", masque]]
|
||||
sock.send(json.dumps(commande).encode("utf-8"))
|
||||
response = get_response(sock)
|
||||
retcode = response['retcode']
|
||||
retcode = response["retcode"]
|
||||
if retcode == 0:
|
||||
return (True, sock, "")
|
||||
elif retcode == 5:
|
||||
|
@ -60,11 +62,28 @@ def don(sock, montant, id_note, facture):
|
|||
Faire faire un don à l'id_note
|
||||
"""
|
||||
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)
|
||||
retcode = response['retcode']
|
||||
retcode = response["retcode"]
|
||||
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 ?)")
|
||||
elif retcode == 0:
|
||||
return (True, "")
|
||||
|
|
|
@ -23,8 +23,6 @@ from . import views
|
|||
|
||||
urlpatterns = [
|
||||
url(
|
||||
r'^note_payment/(?P<factureid>[0-9]+)$',
|
||||
views.note_payment,
|
||||
name='note_payment'
|
||||
),
|
||||
r"^note_payment/(?P<factureid>[0-9]+)$", views.note_payment, name="note_payment"
|
||||
)
|
||||
]
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
# quelques clics.
|
||||
#
|
||||
# Copyright © 2018 Gabriel Detraz
|
||||
# Copyright © 2018 Pierre-Antoine Comby
|
||||
# Copyright © 2018 Pierre-Antoine Comby
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -39,13 +39,11 @@ from cotisations.models import Facture
|
|||
from cotisations.utils import find_payment_method
|
||||
from .models import NotePayment
|
||||
from re2o.views import form
|
||||
from re2o.acl import (
|
||||
can_create,
|
||||
can_edit
|
||||
)
|
||||
from re2o.acl import can_create, can_edit
|
||||
from .note import login, don
|
||||
from .forms import NoteCredentialForm
|
||||
|
||||
|
||||
@login_required
|
||||
@can_edit(Facture)
|
||||
def note_payment(request, facture, factureid):
|
||||
|
@ -58,40 +56,38 @@ def note_payment(request, facture, factureid):
|
|||
payment_method = find_payment_method(facture.paiement)
|
||||
if not payment_method or not isinstance(payment_method, NotePayment):
|
||||
messages.error(request, _("Unknown error."))
|
||||
return redirect(reverse(
|
||||
'users:profil',
|
||||
kwargs={'userid': user.id}
|
||||
))
|
||||
return redirect(reverse("users:profil", kwargs={"userid": user.id}))
|
||||
noteform = NoteCredentialForm(request.POST or None)
|
||||
if noteform.is_valid():
|
||||
pseudo = noteform.cleaned_data['login']
|
||||
password = noteform.cleaned_data['password']
|
||||
result, sock, err = login(payment_method.server, payment_method.port, pseudo, password)
|
||||
pseudo = noteform.cleaned_data["login"]
|
||||
password = noteform.cleaned_data["password"]
|
||||
result, sock, err = login(
|
||||
payment_method.server, payment_method.port, pseudo, password
|
||||
)
|
||||
if not result:
|
||||
messages.error(request, err)
|
||||
return form(
|
||||
{'form': noteform, 'amount': facture.prix_total()},
|
||||
{"form": noteform, "amount": facture.prix_total()},
|
||||
"cotisations/payment.html",
|
||||
request
|
||||
request,
|
||||
)
|
||||
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:
|
||||
messages.error(request, err)
|
||||
return form(
|
||||
{'form': noteform, 'amount': facture.prix_total()},
|
||||
{"form": noteform, "amount": facture.prix_total()},
|
||||
"cotisations/payment.html",
|
||||
request
|
||||
request,
|
||||
)
|
||||
facture.valid = True
|
||||
facture.save()
|
||||
messages.success(request, _("The payment with note was done."))
|
||||
return redirect(reverse(
|
||||
'users:profil',
|
||||
kwargs={'userid': user.id}
|
||||
))
|
||||
return redirect(reverse("users:profil", kwargs={"userid": user.id}))
|
||||
return form(
|
||||
{'form': noteform, 'amount': facture.prix_total()},
|
||||
"cotisations/payment.html",
|
||||
request
|
||||
)
|
||||
{"form": noteform, "amount": facture.prix_total()},
|
||||
"cotisations/payment.html",
|
||||
request,
|
||||
)
|
||||
|
|
|
@ -22,7 +22,7 @@ from django.conf.urls import include, url
|
|||
from . import comnpay, cheque, note_kfet
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^comnpay/', include(comnpay.urls, namespace='comnpay')),
|
||||
url(r'^cheque/', include(cheque.urls, namespace='cheque')),
|
||||
url(r'^note_kfet/', include(note_kfet.urls, namespace='note_kfet')),
|
||||
url(r"^comnpay/", include(comnpay.urls, namespace="comnpay")),
|
||||
url(r"^cheque/", include(cheque.urls, namespace="cheque")),
|
||||
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 .models import Vente, Facture, Cotisation, Paiement
|
||||
|
||||
|
||||
class VenteModelTests(TestCase):
|
||||
def setUp(self):
|
||||
self.user = User.objects.create(
|
||||
pseudo="testUser",
|
||||
email="test@example.org"
|
||||
)
|
||||
self.paiement = Paiement.objects.create(
|
||||
moyen="test payment"
|
||||
)
|
||||
self.user = User.objects.create(pseudo="testUser", email="test@example.org")
|
||||
self.paiement = Paiement.objects.create(moyen="test payment")
|
||||
self.f = Facture.objects.create(
|
||||
user=self.user,
|
||||
paiement=self.paiement,
|
||||
valid=True
|
||||
user=self.user, paiement=self.paiement, valid=True
|
||||
)
|
||||
|
||||
def test_one_day_cotisation(self):
|
||||
|
@ -39,7 +33,7 @@ class VenteModelTests(TestCase):
|
|||
self.assertAlmostEqual(
|
||||
self.user.end_connexion() - date,
|
||||
datetime.timedelta(days=1),
|
||||
delta=datetime.timedelta(seconds=1)
|
||||
delta=datetime.timedelta(seconds=1),
|
||||
)
|
||||
|
||||
def test_one_month_cotisation(self):
|
||||
|
@ -57,11 +51,8 @@ class VenteModelTests(TestCase):
|
|||
prix=0,
|
||||
)
|
||||
delta = relativedelta(self.user.end_connexion(), date)
|
||||
delta.microseconds=0
|
||||
self.assertEqual(
|
||||
delta,
|
||||
relativedelta(months=1),
|
||||
)
|
||||
delta.microseconds = 0
|
||||
self.assertEqual(delta, relativedelta(months=1))
|
||||
|
||||
def test_one_month_and_one_week_cotisation(self):
|
||||
"""
|
||||
|
@ -78,15 +69,10 @@ class VenteModelTests(TestCase):
|
|||
prix=0,
|
||||
)
|
||||
delta = relativedelta(self.user.end_connexion(), date)
|
||||
delta.microseconds=0
|
||||
self.assertEqual(
|
||||
delta,
|
||||
relativedelta(months=1, days=7),
|
||||
)
|
||||
delta.microseconds = 0
|
||||
self.assertEqual(delta, relativedelta(months=1, days=7))
|
||||
|
||||
def tearDown(self):
|
||||
self.f.delete()
|
||||
self.user.delete()
|
||||
self.paiement.delete()
|
||||
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ from django.utils import timezone
|
|||
from users.models import Adherent
|
||||
from .models import Vente, Facture, Cotisation, Paiement, Article
|
||||
|
||||
|
||||
class NewFactureTests(TestCase):
|
||||
def tearDown(self):
|
||||
self.user.facture_set.all().delete()
|
||||
|
@ -19,51 +20,46 @@ class NewFactureTests(TestCase):
|
|||
self.article_one_month_and_one_week.delete()
|
||||
|
||||
def setUp(self):
|
||||
self.user = Adherent.objects.create(
|
||||
pseudo="testUser",
|
||||
email="test@example.org",
|
||||
)
|
||||
self.user.set_password('plopiplop')
|
||||
self.user = Adherent.objects.create(pseudo="testUser", email="test@example.org")
|
||||
self.user.set_password("plopiplop")
|
||||
self.user.user_permissions.set(
|
||||
[
|
||||
Permission.objects.get_by_natural_key("add_facture", "cotisations", "Facture"),
|
||||
Permission.objects.get_by_natural_key("use_every_payment", "cotisations", "Paiement"),
|
||||
Permission.objects.get_by_natural_key(
|
||||
"add_facture", "cotisations", "Facture"
|
||||
),
|
||||
Permission.objects.get_by_natural_key(
|
||||
"use_every_payment", "cotisations", "Paiement"
|
||||
),
|
||||
]
|
||||
)
|
||||
self.user.save()
|
||||
|
||||
self.paiement = Paiement.objects.create(
|
||||
moyen="test payment",
|
||||
|
||||
)
|
||||
self.paiement = Paiement.objects.create(moyen="test payment")
|
||||
self.article_one_day = Article.objects.create(
|
||||
name="One day",
|
||||
prix=0,
|
||||
duration=0,
|
||||
duration_days=1,
|
||||
type_cotisation='All',
|
||||
available_for_everyone=True
|
||||
type_cotisation="All",
|
||||
available_for_everyone=True,
|
||||
)
|
||||
self.article_one_month = Article.objects.create(
|
||||
name="One day",
|
||||
prix=0,
|
||||
duration=1,
|
||||
duration_days=0,
|
||||
type_cotisation='All',
|
||||
available_for_everyone=True
|
||||
type_cotisation="All",
|
||||
available_for_everyone=True,
|
||||
)
|
||||
self.article_one_month_and_one_week = Article.objects.create(
|
||||
name="One day",
|
||||
prix=0,
|
||||
duration=1,
|
||||
duration_days=7,
|
||||
type_cotisation='All',
|
||||
available_for_everyone=True
|
||||
)
|
||||
self.client.login(
|
||||
username="testUser",
|
||||
password="plopiplop"
|
||||
type_cotisation="All",
|
||||
available_for_everyone=True,
|
||||
)
|
||||
self.client.login(username="testUser", password="plopiplop")
|
||||
|
||||
def test_invoice_with_one_day(self):
|
||||
data = {
|
||||
|
@ -76,19 +72,15 @@ class NewFactureTests(TestCase):
|
|||
"form-0-quantity": 1,
|
||||
}
|
||||
date = timezone.now()
|
||||
response = self.client.post(reverse('cotisations:new-facture', kwargs={'userid':self.user.pk}), data)
|
||||
self.assertEqual(
|
||||
response.status_code,
|
||||
302
|
||||
)
|
||||
self.assertEqual(
|
||||
response.url,
|
||||
"/users/profil/%d"%self.user.pk
|
||||
response = self.client.post(
|
||||
reverse("cotisations:new-facture", kwargs={"userid": self.user.pk}), data
|
||||
)
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertEqual(response.url, "/users/profil/%d" % self.user.pk)
|
||||
self.assertAlmostEqual(
|
||||
self.user.end_connexion() - date,
|
||||
datetime.timedelta(days=1),
|
||||
delta=datetime.timedelta(seconds=1)
|
||||
delta=datetime.timedelta(seconds=1),
|
||||
)
|
||||
|
||||
def test_invoice_with_one_month(self):
|
||||
|
@ -102,21 +94,14 @@ class NewFactureTests(TestCase):
|
|||
"form-0-quantity": 1,
|
||||
}
|
||||
date = timezone.now()
|
||||
response = self.client.post(reverse('cotisations:new-facture', kwargs={'userid':self.user.pk}), data)
|
||||
self.assertEqual(
|
||||
response.status_code,
|
||||
302
|
||||
)
|
||||
self.assertEqual(
|
||||
response.url,
|
||||
"/users/profil/%d"%self.user.pk
|
||||
response = self.client.post(
|
||||
reverse("cotisations:new-facture", kwargs={"userid": self.user.pk}), data
|
||||
)
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertEqual(response.url, "/users/profil/%d" % self.user.pk)
|
||||
delta = relativedelta(self.user.end_connexion(), date)
|
||||
delta.microseconds=0
|
||||
self.assertEqual(
|
||||
delta,
|
||||
relativedelta(months=1),
|
||||
)
|
||||
delta.microseconds = 0
|
||||
self.assertEqual(delta, relativedelta(months=1))
|
||||
|
||||
def test_invoice_with_one_month_and_one_week(self):
|
||||
data = {
|
||||
|
@ -131,23 +116,15 @@ class NewFactureTests(TestCase):
|
|||
"form-1-quantity": 1,
|
||||
}
|
||||
date = timezone.now()
|
||||
response = self.client.post(reverse('cotisations:new-facture', kwargs={'userid':self.user.pk}), data)
|
||||
self.assertEqual(
|
||||
response.status_code,
|
||||
302
|
||||
)
|
||||
self.assertEqual(
|
||||
response.url,
|
||||
"/users/profil/%d"%self.user.pk
|
||||
response = self.client.post(
|
||||
reverse("cotisations:new-facture", kwargs={"userid": self.user.pk}), data
|
||||
)
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertEqual(response.url, "/users/profil/%d" % self.user.pk)
|
||||
invoice = self.user.facture_set.first()
|
||||
delta = relativedelta(self.user.end_connexion(), date)
|
||||
delta.microseconds=0
|
||||
self.assertEqual(
|
||||
delta,
|
||||
relativedelta(months=1, days=7),
|
||||
)
|
||||
|
||||
delta.microseconds = 0
|
||||
self.assertEqual(delta, relativedelta(months=1, days=7))
|
||||
|
||||
def test_several_articles_creates_several_purchases(self):
|
||||
data = {
|
||||
|
@ -161,6 +138,8 @@ class NewFactureTests(TestCase):
|
|||
"form-1-article": 2,
|
||||
"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()
|
||||
self.assertEqual(f.vente_set.count(), 2)
|
||||
|
|
|
@ -42,9 +42,9 @@ from re2o.mixins import AclMixin, RevMixin
|
|||
from preferences.models import CotisationsOption
|
||||
|
||||
|
||||
TEMP_PREFIX = getattr(settings, 'TEX_TEMP_PREFIX', 'render_tex-')
|
||||
CACHE_PREFIX = getattr(settings, 'TEX_CACHE_PREFIX', 'render-tex')
|
||||
CACHE_TIMEOUT = getattr(settings, 'TEX_CACHE_TIMEOUT', 86400) # 1 day
|
||||
TEMP_PREFIX = getattr(settings, "TEX_TEMP_PREFIX", "render_tex-")
|
||||
CACHE_PREFIX = getattr(settings, "TEX_CACHE_PREFIX", "render-tex")
|
||||
CACHE_TIMEOUT = getattr(settings, "TEX_CACHE_TIMEOUT", 86400) # 1 day
|
||||
|
||||
|
||||
def render_invoice(_request, ctx={}):
|
||||
|
@ -53,20 +53,20 @@ def render_invoice(_request, ctx={}):
|
|||
date, the user, the articles, the prices, ...
|
||||
"""
|
||||
options, _ = CotisationsOption.objects.get_or_create()
|
||||
is_estimate = ctx.get('is_estimate', False)
|
||||
filename = '_'.join([
|
||||
'cost_estimate' if is_estimate else 'invoice',
|
||||
slugify(ctx.get('asso_name', "")),
|
||||
slugify(ctx.get('recipient_name', "")),
|
||||
str(ctx.get('DATE', datetime.now()).year),
|
||||
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
|
||||
is_estimate = ctx.get("is_estimate", False)
|
||||
filename = "_".join(
|
||||
[
|
||||
"cost_estimate" if is_estimate else "invoice",
|
||||
slugify(ctx.get("asso_name", "")),
|
||||
slugify(ctx.get("recipient_name", "")),
|
||||
str(ctx.get("DATE", datetime.now()).year),
|
||||
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)
|
||||
return r
|
||||
|
||||
|
||||
|
@ -75,20 +75,20 @@ def render_voucher(_request, ctx={}):
|
|||
Render a subscribtion voucher.
|
||||
"""
|
||||
options, _ = CotisationsOption.objects.get_or_create()
|
||||
filename = '_'.join([
|
||||
'voucher',
|
||||
slugify(ctx.get('asso_name', "")),
|
||||
slugify(ctx.get('firstname', "")),
|
||||
slugify(ctx.get('lastname', "")),
|
||||
str(ctx.get('date_begin', datetime.now()).year),
|
||||
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
|
||||
filename = "_".join(
|
||||
[
|
||||
"voucher",
|
||||
slugify(ctx.get("asso_name", "")),
|
||||
slugify(ctx.get("firstname", "")),
|
||||
slugify(ctx.get("lastname", "")),
|
||||
str(ctx.get("date_begin", datetime.now()).year),
|
||||
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)
|
||||
return r
|
||||
|
||||
|
||||
|
@ -106,18 +106,18 @@ def create_pdf(template, ctx={}):
|
|||
"""
|
||||
context = ctx
|
||||
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:
|
||||
for _ in range(2):
|
||||
with open("/var/www/re2o/out.log", "w") as f:
|
||||
process = Popen(
|
||||
['pdflatex', '-output-directory', tempdir],
|
||||
["pdflatex", "-output-directory", tempdir],
|
||||
stdin=PIPE,
|
||||
stdout=f,#PIPE,
|
||||
stdout=f, # PIPE,
|
||||
)
|
||||
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()
|
||||
|
||||
return pdf
|
||||
|
@ -127,10 +127,7 @@ def escape_chars(string):
|
|||
"""Escape the '%' and the '€' signs to avoid messing with LaTeX"""
|
||||
if not isinstance(string, str):
|
||||
return string
|
||||
mapping = (
|
||||
('€', r'\euro'),
|
||||
('%', r'\%'),
|
||||
)
|
||||
mapping = (("€", r"\euro"), ("%", r"\%"))
|
||||
r = str(string)
|
||||
for k, v in mapping:
|
||||
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.
|
||||
"""
|
||||
pdf = create_pdf(template, ctx)
|
||||
r = HttpResponse(content_type='application/pdf')
|
||||
r = HttpResponse(content_type="application/pdf")
|
||||
r.write(pdf)
|
||||
return r
|
||||
|
|
|
@ -31,155 +31,77 @@ from . import views
|
|||
from . import payment_methods
|
||||
|
||||
urlpatterns = [
|
||||
url(r"^new_facture/(?P<userid>[0-9]+)$", views.new_facture, name="new-facture"),
|
||||
url(
|
||||
r'^new_facture/(?P<userid>[0-9]+)$',
|
||||
views.new_facture,
|
||||
name='new-facture'
|
||||
r"^edit_facture/(?P<factureid>[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'^edit_facture/(?P<factureid>[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]+)$',
|
||||
r"^cost_estimate_pdf/(?P<costestimateid>[0-9]+)$",
|
||||
views.cost_estimate_pdf,
|
||||
name='cost-estimate-pdf',
|
||||
name="cost-estimate-pdf",
|
||||
),
|
||||
url(
|
||||
r'^index_custom_invoice/$',
|
||||
r"^index_custom_invoice/$",
|
||||
views.index_custom_invoice,
|
||||
name='index-custom-invoice'
|
||||
name="index-custom-invoice",
|
||||
),
|
||||
url(
|
||||
r'^edit_cost_estimate/(?P<costestimateid>[0-9]+)$',
|
||||
r"^edit_cost_estimate/(?P<costestimateid>[0-9]+)$",
|
||||
views.edit_cost_estimate,
|
||||
name='edit-cost-estimate'
|
||||
name="edit-cost-estimate",
|
||||
),
|
||||
url(
|
||||
r'^cost_estimate_to_invoice/(?P<costestimateid>[0-9]+)$',
|
||||
r"^cost_estimate_to_invoice/(?P<costestimateid>[0-9]+)$",
|
||||
views.cost_estimate_to_invoice,
|
||||
name='cost-estimate-to-invoice'
|
||||
name="cost-estimate-to-invoice",
|
||||
),
|
||||
url(
|
||||
r'^del_cost_estimate/(?P<costestimateid>[0-9]+)$',
|
||||
r"^del_cost_estimate/(?P<costestimateid>[0-9]+)$",
|
||||
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(
|
||||
r'^new_custom_invoice/$',
|
||||
views.new_custom_invoice,
|
||||
name='new-custom-invoice'
|
||||
),
|
||||
url(
|
||||
r'^edit_custom_invoice/(?P<custominvoiceid>[0-9]+)$',
|
||||
r"^edit_custom_invoice/(?P<custominvoiceid>[0-9]+)$",
|
||||
views.edit_custom_invoice,
|
||||
name='edit-custom-invoice'
|
||||
name="edit-custom-invoice",
|
||||
),
|
||||
url(
|
||||
r'^custom_invoice_pdf/(?P<custominvoiceid>[0-9]+)$',
|
||||
r"^custom_invoice_pdf/(?P<custominvoiceid>[0-9]+)$",
|
||||
views.custom_invoice_pdf,
|
||||
name='custom-invoice-pdf',
|
||||
name="custom-invoice-pdf",
|
||||
),
|
||||
url(
|
||||
r'^del_custom_invoice/(?P<custominvoiceid>[0-9]+)$',
|
||||
r"^del_custom_invoice/(?P<custominvoiceid>[0-9]+)$",
|
||||
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(
|
||||
r'^credit_solde/(?P<userid>[0-9]+)$',
|
||||
views.credit_solde,
|
||||
name='credit-solde'
|
||||
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'^add_article/$',
|
||||
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]+)$',
|
||||
r"^edit_paiement/(?P<paiementid>[0-9]+)$",
|
||||
views.edit_paiement,
|
||||
name='edit-paiement'
|
||||
name="edit-paiement",
|
||||
),
|
||||
url(
|
||||
r'^del_paiement/$',
|
||||
views.del_paiement,
|
||||
name='del-paiement'
|
||||
),
|
||||
url(
|
||||
r'^add_banque/$',
|
||||
views.add_banque,
|
||||
name='add-banque'
|
||||
),
|
||||
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'),
|
||||
url(r"^del_paiement/$", views.del_paiement, name="del-paiement"),
|
||||
url(r"^add_banque/$", views.add_banque, name="add-banque"),
|
||||
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
|
||||
|
|
|
@ -25,9 +25,7 @@ from django.template.loader import get_template
|
|||
from django.core.mail import EmailMessage
|
||||
|
||||
from .tex import create_pdf
|
||||
from preferences.models import (
|
||||
AssoOption, GeneralOption, CotisationsOption, Mandate
|
||||
)
|
||||
from preferences.models import AssoOption, GeneralOption, CotisationsOption, Mandate
|
||||
from re2o.settings import LOGO_PATH
|
||||
from re2o import settings
|
||||
|
||||
|
@ -35,6 +33,7 @@ from re2o import settings
|
|||
def find_payment_method(payment):
|
||||
"""Finds the payment method associated to the payment if it exists."""
|
||||
from cotisations.payment_methods import PAYMENT_METHODS
|
||||
|
||||
for method in PAYMENT_METHODS:
|
||||
try:
|
||||
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"""
|
||||
purchases_info = []
|
||||
for purchase in invoice.vente_set.all():
|
||||
purchases_info.append({
|
||||
'name': purchase.name,
|
||||
'price': purchase.prix,
|
||||
'quantity': purchase.number,
|
||||
'total_price': purchase.prix_total
|
||||
})
|
||||
purchases_info.append(
|
||||
{
|
||||
"name": purchase.name,
|
||||
"price": purchase.prix,
|
||||
"quantity": purchase.number,
|
||||
"total_price": purchase.prix_total,
|
||||
}
|
||||
)
|
||||
|
||||
ctx = {
|
||||
'paid': True,
|
||||
'fid': invoice.id,
|
||||
'DATE': invoice.date,
|
||||
'recipient_name': "{} {}".format(
|
||||
invoice.user.name,
|
||||
invoice.user.surname
|
||||
),
|
||||
'address': invoice.user.room,
|
||||
'article': purchases_info,
|
||||
'total': invoice.prix_total(),
|
||||
'asso_name': AssoOption.get_cached_value('name'),
|
||||
'line1': AssoOption.get_cached_value('adresse1'),
|
||||
'line2': AssoOption.get_cached_value('adresse2'),
|
||||
'siret': AssoOption.get_cached_value('siret'),
|
||||
'email': AssoOption.get_cached_value('contact'),
|
||||
'phone': AssoOption.get_cached_value('telephone'),
|
||||
'tpl_path': os.path.join(settings.BASE_DIR, LOGO_PATH)
|
||||
"paid": True,
|
||||
"fid": invoice.id,
|
||||
"DATE": invoice.date,
|
||||
"recipient_name": "{} {}".format(invoice.user.name, invoice.user.surname),
|
||||
"address": invoice.user.room,
|
||||
"article": purchases_info,
|
||||
"total": invoice.prix_total(),
|
||||
"asso_name": AssoOption.get_cached_value("name"),
|
||||
"line1": AssoOption.get_cached_value("adresse1"),
|
||||
"line2": AssoOption.get_cached_value("adresse2"),
|
||||
"siret": AssoOption.get_cached_value("siret"),
|
||||
"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)
|
||||
template = get_template('cotisations/email_invoice')
|
||||
pdf = create_pdf("cotisations/factures.tex", ctx)
|
||||
template = get_template("cotisations/email_invoice")
|
||||
|
||||
ctx = {
|
||||
'name': "{} {}".format(
|
||||
invoice.user.name,
|
||||
invoice.user.surname
|
||||
),
|
||||
'contact_mail': AssoOption.get_cached_value('contact'),
|
||||
'asso_name': AssoOption.get_cached_value('name')
|
||||
"name": "{} {}".format(invoice.user.name, invoice.user.surname),
|
||||
"contact_mail": AssoOption.get_cached_value("contact"),
|
||||
"asso_name": AssoOption.get_cached_value("name"),
|
||||
}
|
||||
|
||||
mail = EmailMessage(
|
||||
'Votre facture / Your invoice',
|
||||
"Votre facture / Your invoice",
|
||||
template.render(ctx),
|
||||
GeneralOption.get_cached_value('email_from'),
|
||||
GeneralOption.get_cached_value("email_from"),
|
||||
[invoice.user.get_mail],
|
||||
attachments=[('invoice.pdf', pdf, 'application/pdf')]
|
||||
attachments=[("invoice.pdf", pdf, "application/pdf")],
|
||||
)
|
||||
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"""
|
||||
president = Mandate.get_mandate(invoice.date).president
|
||||
ctx = {
|
||||
'asso_name': AssoOption.get_cached_value('name'),
|
||||
'pres_name': ' '.join([president.name, president.surname]),
|
||||
'firstname': invoice.user.name,
|
||||
'lastname': invoice.user.surname,
|
||||
'email': invoice.user.email,
|
||||
'phone': invoice.user.telephone,
|
||||
'date_end': invoice.get_subscription().latest('date_end').date_end,
|
||||
'date_begin': invoice.get_subscription().earliest('date_start').date_start
|
||||
"asso_name": AssoOption.get_cached_value("name"),
|
||||
"pres_name": " ".join([president.name, president.surname]),
|
||||
"firstname": invoice.user.name,
|
||||
"lastname": invoice.user.surname,
|
||||
"email": invoice.user.email,
|
||||
"phone": invoice.user.telephone,
|
||||
"date_end": invoice.get_subscription().latest("date_end").date_end,
|
||||
"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)
|
||||
template = get_template('cotisations/email_subscription_accepted')
|
||||
template = get_template("cotisations/email_subscription_accepted")
|
||||
|
||||
ctx = {
|
||||
'name': "{} {}".format(
|
||||
invoice.user.name,
|
||||
invoice.user.surname
|
||||
),
|
||||
'asso_email': AssoOption.get_cached_value('contact'),
|
||||
'asso_name': AssoOption.get_cached_value('name'),
|
||||
'date_end': invoice.get_subscription().latest('date_end').date_end,
|
||||
"name": "{} {}".format(invoice.user.name, invoice.user.surname),
|
||||
"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(
|
||||
'Votre reçu / Your voucher',
|
||||
"Votre reçu / Your voucher",
|
||||
template.render(ctx),
|
||||
GeneralOption.get_cached_value('email_from'),
|
||||
GeneralOption.get_cached_value("email_from"),
|
||||
[invoice.user.get_mail],
|
||||
attachments=[('voucher.pdf', pdf, 'application/pdf')]
|
||||
attachments=[("voucher.pdf", pdf, "application/pdf")],
|
||||
)
|
||||
mail.send()
|
||||
|
|
|
@ -12,11 +12,9 @@ def check_no_balance(is_balance):
|
|||
ValidationError: if such a Paiement exists.
|
||||
"""
|
||||
from .models import Paiement
|
||||
|
||||
if not is_balance:
|
||||
return
|
||||
p = Paiement.objects.filter(is_balance=True)
|
||||
if len(p) > 0:
|
||||
raise ValidationError(
|
||||
_("There is already a payment method for user balance.")
|
||||
)
|
||||
|
||||
raise ValidationError(_("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)
|
||||
TEST_SERVER = bool(os.getenv('DBG_FREERADIUS', False))
|
||||
TEST_SERVER = bool(os.getenv("DBG_FREERADIUS", False))
|
||||
|
||||
|
||||
# Logging
|
||||
|
@ -77,13 +77,13 @@ class RadiusdHandler(logging.Handler):
|
|||
rad_sig = radiusd.L_INFO
|
||||
else:
|
||||
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é)
|
||||
logger = logging.getLogger('auth.py')
|
||||
logger = logging.getLogger("auth.py")
|
||||
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.setFormatter(formatter)
|
||||
logger.addHandler(handler)
|
||||
|
@ -111,17 +111,16 @@ def radius_event(fun):
|
|||
for (key, value) in auth_data or []:
|
||||
# Beware: les valeurs scalaires sont entre guillemets
|
||||
# Ex: Calling-Station-Id: "une_adresse_mac"
|
||||
data[key] = value.replace('"', '')
|
||||
data[key] = value.replace('"', "")
|
||||
try:
|
||||
# TODO s'assurer ici que les tuples renvoyés sont bien des
|
||||
# (str,str) : rlm_python ne digère PAS les unicodes
|
||||
return fun(data)
|
||||
except Exception as err:
|
||||
exc_type, exc_instance, exc_traceback = sys.exc_info()
|
||||
formatted_traceback = ''.join(traceback.format_tb(
|
||||
exc_traceback))
|
||||
logger.error('Failed %r on data %r' % (err, auth_data))
|
||||
logger.error('Function %r, Traceback : %r' % (fun, formatted_traceback))
|
||||
formatted_traceback = "".join(traceback.format_tb(exc_traceback))
|
||||
logger.error("Failed %r on data %r" % (err, auth_data))
|
||||
logger.error("Function %r, Traceback : %r" % (fun, formatted_traceback))
|
||||
return radiusd.RLM_MODULE_FAIL
|
||||
|
||||
return new_f
|
||||
|
@ -131,9 +130,9 @@ def radius_event(fun):
|
|||
def instantiate(*_):
|
||||
"""Utile pour initialiser les connexions ldap une première fois (otherwise,
|
||||
do nothing)"""
|
||||
logger.info('Instantiation')
|
||||
logger.info("Instantiation")
|
||||
if TEST_SERVER:
|
||||
logger.info(u'DBG_FREERADIUS is enabled')
|
||||
logger.info(u"DBG_FREERADIUS is enabled")
|
||||
|
||||
|
||||
@radius_event
|
||||
|
@ -146,23 +145,19 @@ def authorize(data):
|
|||
accept en authorize
|
||||
"""
|
||||
# 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)
|
||||
# Toutes les reuquètes non proxifiées
|
||||
nas_type = None
|
||||
if nas_instance:
|
||||
nas_type = Nas.objects.filter(nas_type=nas_instance.machine_type).first()
|
||||
if not nas_type or nas_type.port_access_mode == '802.1X':
|
||||
user = data.get('User-Name', '').decode('utf-8', errors='replace')
|
||||
user = user.split('@', 1)[0]
|
||||
mac = data.get('Calling-Station-Id', '')
|
||||
result, log, password = check_user_machine_and_register(
|
||||
nas_type,
|
||||
user,
|
||||
mac
|
||||
)
|
||||
logger.info(log.encode('utf-8'))
|
||||
logger.info(user.encode('utf-8'))
|
||||
if not nas_type or nas_type.port_access_mode == "802.1X":
|
||||
user = data.get("User-Name", "").decode("utf-8", errors="replace")
|
||||
user = user.split("@", 1)[0]
|
||||
mac = data.get("Calling-Station-Id", "")
|
||||
result, log, password = check_user_machine_and_register(nas_type, user, mac)
|
||||
logger.info(log.encode("utf-8"))
|
||||
logger.info(user.encode("utf-8"))
|
||||
|
||||
if not result:
|
||||
return radiusd.RLM_MODULE_REJECT
|
||||
|
@ -170,19 +165,11 @@ def authorize(data):
|
|||
return (
|
||||
radiusd.RLM_MODULE_UPDATED,
|
||||
(),
|
||||
(
|
||||
(str("NT-Password"), str(password)),
|
||||
),
|
||||
((str("NT-Password"), str(password)),),
|
||||
)
|
||||
|
||||
else:
|
||||
return (
|
||||
radiusd.RLM_MODULE_UPDATED,
|
||||
(),
|
||||
(
|
||||
("Auth-Type", "Accept"),
|
||||
),
|
||||
)
|
||||
return (radiusd.RLM_MODULE_UPDATED, (), (("Auth-Type", "Accept"),))
|
||||
|
||||
|
||||
@radius_event
|
||||
|
@ -190,52 +177,49 @@ def post_auth(data):
|
|||
""" 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)
|
||||
# Toutes les reuquètes non proxifiées
|
||||
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
|
||||
nas_type = Nas.objects.filter(nas_type=nas_instance.machine_type).first()
|
||||
if not nas_type:
|
||||
logger.info(
|
||||
u"Type de nas non enregistre dans la bdd!".encode('utf-8')
|
||||
)
|
||||
logger.info(u"Type de nas non enregistre dans la bdd!".encode("utf-8"))
|
||||
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
|
||||
# interfaces filles
|
||||
nas_machine = nas_instance.machine
|
||||
# Si il s'agit d'un switch
|
||||
if hasattr(nas_machine, 'switch'):
|
||||
port = data.get('NAS-Port-Id', data.get('NAS-Port', None))
|
||||
if hasattr(nas_machine, "switch"):
|
||||
port = data.get("NAS-Port-Id", data.get("NAS-Port", None))
|
||||
# Pour les infrastructures possédant des switchs Juniper :
|
||||
# On vérifie si le switch fait partie d'un stack Juniper
|
||||
instance_stack = nas_machine.switch.stack
|
||||
if instance_stack:
|
||||
# Si c'est le cas, on resélectionne le bon switch dans la stack
|
||||
id_stack_member = port.split("-")[1].split('/')[0]
|
||||
nas_machine = (Switch.objects
|
||||
.filter(stack=instance_stack)
|
||||
.filter(stack_member_id=id_stack_member)
|
||||
.prefetch_related(
|
||||
'interface_set__domain__extension'
|
||||
)
|
||||
.first())
|
||||
id_stack_member = port.split("-")[1].split("/")[0]
|
||||
nas_machine = (
|
||||
Switch.objects.filter(stack=instance_stack)
|
||||
.filter(stack_member_id=id_stack_member)
|
||||
.prefetch_related("interface_set__domain__extension")
|
||||
.first()
|
||||
)
|
||||
# On récupère le numéro du port sur l'output de freeradius.
|
||||
# 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)
|
||||
sw_name, room, reason, vlan_id, decision, attributes = out
|
||||
|
||||
if decision:
|
||||
log_message = '(fil) %s -> %s [%s%s]' % (
|
||||
log_message = "(fil) %s -> %s [%s%s]" % (
|
||||
sw_name + u":" + port + u"/" + str(room),
|
||||
mac,
|
||||
vlan_id,
|
||||
(reason and u': ' + reason).encode('utf-8')
|
||||
(reason and u": " + reason).encode("utf-8"),
|
||||
)
|
||||
logger.info(log_message)
|
||||
|
||||
|
@ -245,23 +229,20 @@ def post_auth(data):
|
|||
(
|
||||
("Tunnel-Type", "VLAN"),
|
||||
("Tunnel-Medium-Type", "IEEE-802"),
|
||||
("Tunnel-Private-Group-Id", '%d' % int(vlan_id)),
|
||||
) + tuple(attributes),
|
||||
()
|
||||
("Tunnel-Private-Group-Id", "%d" % int(vlan_id)),
|
||||
)
|
||||
+ tuple(attributes),
|
||||
(),
|
||||
)
|
||||
else:
|
||||
log_message = '(fil) %s -> %s [Reject:%s]' % (
|
||||
log_message = "(fil) %s -> %s [Reject:%s]" % (
|
||||
sw_name + u":" + port + u"/" + str(room),
|
||||
mac,
|
||||
(reason and u': ' + reason).encode('utf-8')
|
||||
(reason and u": " + reason).encode("utf-8"),
|
||||
)
|
||||
logger.info(log_message)
|
||||
|
||||
return (
|
||||
radiusd.RLM_MODULE_REJECT,
|
||||
tuple(attributes),
|
||||
()
|
||||
)
|
||||
return (radiusd.RLM_MODULE_REJECT, tuple(attributes), ())
|
||||
|
||||
else:
|
||||
return radiusd.RLM_MODULE_OK
|
||||
|
@ -282,13 +263,14 @@ def detach(_=None):
|
|||
|
||||
def find_nas_from_request(nas_id):
|
||||
""" Get the nas object from its ID """
|
||||
nas = (Interface.objects
|
||||
.filter(
|
||||
Q(domain=Domain.objects.filter(name=nas_id)) |
|
||||
Q(ipv4=IpList.objects.filter(ipv4=nas_id))
|
||||
)
|
||||
.select_related('machine_type')
|
||||
.select_related('machine__switch__stack'))
|
||||
nas = (
|
||||
Interface.objects.filter(
|
||||
Q(domain=Domain.objects.filter(name=nas_id))
|
||||
| Q(ipv4=IpList.objects.filter(ipv4=nas_id))
|
||||
)
|
||||
.select_related("machine_type")
|
||||
.select_related("machine__switch__stack")
|
||||
)
|
||||
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()
|
||||
user = User.objects.filter(pseudo__iexact=username).first()
|
||||
if not user:
|
||||
return (False, u"User inconnu", '')
|
||||
return (False, u"User inconnu", "")
|
||||
if not user.has_access():
|
||||
return (False, u"Adherent non cotisant", '')
|
||||
return (False, u"Adherent non cotisant", "")
|
||||
if interface:
|
||||
if interface.machine.user != user:
|
||||
return (False,
|
||||
u"Machine enregistree sur le compte d'un autre "
|
||||
"user...",
|
||||
'')
|
||||
return (
|
||||
False,
|
||||
u"Machine enregistree sur le compte d'un autre " "user...",
|
||||
"",
|
||||
)
|
||||
elif not interface.is_active:
|
||||
return (False, u"Machine desactivee", '')
|
||||
return (False, u"Machine desactivee", "")
|
||||
elif not interface.ipv4:
|
||||
interface.assign_ipv4()
|
||||
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:
|
||||
result, reason = user.autoregister_machine(mac_address, nas_type)
|
||||
if result:
|
||||
return (True,
|
||||
u'Access Ok, Capture de la mac...',
|
||||
user.pwd_ntlm)
|
||||
return (True, u"Access Ok, Capture de la mac...", user.pwd_ntlm)
|
||||
else:
|
||||
return (False, u'Erreur dans le register mac %s' % reason, '')
|
||||
return (False, u"Erreur dans le register mac %s" % reason, "")
|
||||
else:
|
||||
return (False, u'Machine inconnue', '')
|
||||
return (False, u"Machine inconnue", "")
|
||||
else:
|
||||
return (False, u"Machine inconnue", '')
|
||||
return (False, u"Machine inconnue", "")
|
||||
|
||||
|
||||
def decide_vlan_switch(nas_machine, nas_type, port_number,
|
||||
mac_address):
|
||||
def decide_vlan_switch(nas_machine, nas_type, port_number, mac_address):
|
||||
"""Fonction de placement vlan pour un switch en radius filaire auth par
|
||||
mac.
|
||||
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)
|
||||
"""
|
||||
attributes_kwargs = {
|
||||
'client_mac' : str(mac_address),
|
||||
'switch_port' : str(port_number),
|
||||
"client_mac": str(mac_address),
|
||||
"switch_port": str(port_number),
|
||||
}
|
||||
# Get port from switch and port number
|
||||
extra_log = ""
|
||||
# Si le NAS est inconnu, on place sur le vlan defaut
|
||||
if not nas_machine:
|
||||
return (
|
||||
'?',
|
||||
u'Chambre inconnue',
|
||||
u'Nas inconnu',
|
||||
RadiusOption.get_cached_value('vlan_decision_ok').vlan_id,
|
||||
"?",
|
||||
u"Chambre inconnue",
|
||||
u"Nas inconnu",
|
||||
RadiusOption.get_cached_value("vlan_decision_ok").vlan_id,
|
||||
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()
|
||||
attributes_kwargs['switch_ip'] = str(switch.ipv4)
|
||||
port = (Port.objects
|
||||
.filter(
|
||||
switch=switch,
|
||||
port=port_number
|
||||
)
|
||||
.first())
|
||||
attributes_kwargs["switch_ip"] = str(switch.ipv4)
|
||||
port = Port.objects.filter(switch=switch, port=port_number).first()
|
||||
|
||||
# Si le port est inconnu, on place sur le vlan defaut
|
||||
# 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 (
|
||||
sw_name,
|
||||
"Port inconnu",
|
||||
u'Port inconnu',
|
||||
getattr(RadiusOption.get_cached_value('unknown_port_vlan'), 'vlan_id', None),
|
||||
RadiusOption.get_cached_value('unknown_port')!= RadiusOption.REJECT,
|
||||
RadiusOption.get_attributes('unknown_port_attributes', attributes_kwargs)
|
||||
u"Port inconnu",
|
||||
getattr(
|
||||
RadiusOption.get_cached_value("unknown_port_vlan"), "vlan_id", None
|
||||
),
|
||||
RadiusOption.get_cached_value("unknown_port") != RadiusOption.REJECT,
|
||||
RadiusOption.get_attributes("unknown_port_attributes", attributes_kwargs),
|
||||
)
|
||||
|
||||
# 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)
|
||||
attributes = ()
|
||||
else:
|
||||
DECISION_VLAN = RadiusOption.get_cached_value('vlan_decision_ok').vlan_id
|
||||
attributes = RadiusOption.get_attributes('ok_attributes', attributes_kwargs)
|
||||
DECISION_VLAN = RadiusOption.get_cached_value("vlan_decision_ok").vlan_id
|
||||
attributes = RadiusOption.get_attributes("ok_attributes", attributes_kwargs)
|
||||
|
||||
# Si le port est désactivé, on rejette la connexion
|
||||
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
|
||||
if port_profile.radius_type == 'NO':
|
||||
return (sw_name,
|
||||
"",
|
||||
u"Pas d'authentification sur ce port" + extra_log,
|
||||
DECISION_VLAN,
|
||||
True,
|
||||
attributes
|
||||
)
|
||||
if port_profile.radius_type == "NO":
|
||||
return (
|
||||
sw_name,
|
||||
"",
|
||||
u"Pas d'authentification sur ce port" + extra_log,
|
||||
DECISION_VLAN,
|
||||
True,
|
||||
attributes,
|
||||
)
|
||||
|
||||
# Si le 802.1X est activé sur ce port, cela veut dire que la personne a
|
||||
# été accept précédemment
|
||||
# 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"
|
||||
return (
|
||||
sw_name,
|
||||
room,
|
||||
u'Acceptation authentification 802.1X',
|
||||
u"Acceptation authentification 802.1X",
|
||||
DECISION_VLAN,
|
||||
True,
|
||||
attributes
|
||||
attributes,
|
||||
)
|
||||
|
||||
# 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)
|
||||
# Il n'est pas possible de se connecter sur une prise strict sans adhérent
|
||||
# à jour de cotis dedans
|
||||
if port_profile.radius_mode == 'STRICT':
|
||||
if port_profile.radius_mode == "STRICT":
|
||||
room = port.room
|
||||
if not room:
|
||||
return (
|
||||
sw_name,
|
||||
"Inconnue",
|
||||
u'Chambre inconnue',
|
||||
getattr(RadiusOption.get_cached_value('unknown_room_vlan'), 'vlan_id', None),
|
||||
RadiusOption.get_cached_value('unknown_room')!= RadiusOption.REJECT,
|
||||
RadiusOption.get_attributes('unknown_room_attributes', attributes_kwargs),
|
||||
u"Chambre inconnue",
|
||||
getattr(
|
||||
RadiusOption.get_cached_value("unknown_room_vlan"), "vlan_id", None
|
||||
),
|
||||
RadiusOption.get_cached_value("unknown_room") != RadiusOption.REJECT,
|
||||
RadiusOption.get_attributes(
|
||||
"unknown_room_attributes", attributes_kwargs
|
||||
),
|
||||
)
|
||||
|
||||
room_user = User.objects.filter(
|
||||
|
@ -479,41 +461,52 @@ def decide_vlan_switch(nas_machine, nas_type, port_number,
|
|||
return (
|
||||
sw_name,
|
||||
room,
|
||||
u'Chambre non cotisante',
|
||||
getattr(RadiusOption.get_cached_value('non_member_vlan'), 'vlan_id', None),
|
||||
RadiusOption.get_cached_value('non_member')!= RadiusOption.REJECT,
|
||||
RadiusOption.get_attributes('non_member_attributes', attributes_kwargs),
|
||||
u"Chambre non cotisante",
|
||||
getattr(
|
||||
RadiusOption.get_cached_value("non_member_vlan"), "vlan_id", None
|
||||
),
|
||||
RadiusOption.get_cached_value("non_member") != RadiusOption.REJECT,
|
||||
RadiusOption.get_attributes("non_member_attributes", attributes_kwargs),
|
||||
)
|
||||
for user in room_user:
|
||||
if user.is_ban() or user.state != User.STATE_ACTIVE:
|
||||
return (
|
||||
sw_name,
|
||||
room,
|
||||
u'Utilisateur banni ou desactive',
|
||||
getattr(RadiusOption.get_cached_value('banned_vlan'), 'vlan_id', None),
|
||||
RadiusOption.get_cached_value('banned')!= RadiusOption.REJECT,
|
||||
RadiusOption.get_attributes('banned_attributes', attributes_kwargs),
|
||||
u"Utilisateur banni ou desactive",
|
||||
getattr(
|
||||
RadiusOption.get_cached_value("banned_vlan"), "vlan_id", None
|
||||
),
|
||||
RadiusOption.get_cached_value("banned") != RadiusOption.REJECT,
|
||||
RadiusOption.get_attributes("banned_attributes", attributes_kwargs),
|
||||
)
|
||||
elif not (user.is_connected() or user.is_whitelisted()):
|
||||
return (
|
||||
sw_name,
|
||||
room,
|
||||
u'Utilisateur non cotisant',
|
||||
getattr(RadiusOption.get_cached_value('non_member_vlan'), 'vlan_id', None),
|
||||
RadiusOption.get_cached_value('non_member')!= RadiusOption.REJECT,
|
||||
RadiusOption.get_attributes('non_member_attributes', attributes_kwargs),
|
||||
u"Utilisateur non cotisant",
|
||||
getattr(
|
||||
RadiusOption.get_cached_value("non_member_vlan"),
|
||||
"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
|
||||
|
||||
# Si on fait de l'auth par mac, on cherche l'interface
|
||||
# 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
|
||||
interface = (Interface.objects
|
||||
.filter(mac_address=mac_address)
|
||||
.select_related('machine__user')
|
||||
.select_related('ipv4')
|
||||
.first())
|
||||
interface = (
|
||||
Interface.objects.filter(mac_address=mac_address)
|
||||
.select_related("machine__user")
|
||||
.select_related("ipv4")
|
||||
.first()
|
||||
)
|
||||
if not interface:
|
||||
room = port.room
|
||||
# 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 (
|
||||
sw_name,
|
||||
room,
|
||||
u'Machine Inconnue',
|
||||
getattr(RadiusOption.get_cached_value('unknown_machine_vlan'), 'vlan_id', None),
|
||||
RadiusOption.get_cached_value('unknown_machine')!= RadiusOption.REJECT,
|
||||
RadiusOption.get_attributes('unknown_machine_attributes', attributes_kwargs),
|
||||
u"Machine Inconnue",
|
||||
getattr(
|
||||
RadiusOption.get_cached_value("unknown_machine_vlan"),
|
||||
"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
|
||||
# radius.
|
||||
|
@ -533,10 +533,17 @@ def decide_vlan_switch(nas_machine, nas_type, port_number,
|
|||
return (
|
||||
sw_name,
|
||||
"",
|
||||
u'Machine inconnue',
|
||||
getattr(RadiusOption.get_cached_value('unknown_machine_vlan'), 'vlan_id', None),
|
||||
RadiusOption.get_cached_value('unknown_machine')!= RadiusOption.REJECT,
|
||||
RadiusOption.get_attributes('unknown_machine_attributes', attributes_kwargs),
|
||||
u"Machine inconnue",
|
||||
getattr(
|
||||
RadiusOption.get_cached_value("unknown_machine_vlan"),
|
||||
"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,
|
||||
|
@ -549,23 +556,31 @@ def decide_vlan_switch(nas_machine, nas_type, port_number,
|
|||
return (
|
||||
sw_name,
|
||||
room,
|
||||
u'Adherent banni',
|
||||
getattr(RadiusOption.get_cached_value('banned_vlan'), 'vlan_id', None),
|
||||
RadiusOption.get_cached_value('banned')!= RadiusOption.REJECT,
|
||||
RadiusOption.get_attributes('banned_attributes', attributes_kwargs),
|
||||
u"Adherent banni",
|
||||
getattr(
|
||||
RadiusOption.get_cached_value("banned_vlan"), "vlan_id", None
|
||||
),
|
||||
RadiusOption.get_cached_value("banned") != RadiusOption.REJECT,
|
||||
RadiusOption.get_attributes("banned_attributes", attributes_kwargs),
|
||||
)
|
||||
if not interface.is_active:
|
||||
return (
|
||||
sw_name,
|
||||
room,
|
||||
u'Machine non active / adherent non cotisant',
|
||||
getattr(RadiusOption.get_cached_value('non_member_vlan'), 'vlan_id', None),
|
||||
RadiusOption.get_cached_value('non_member')!= RadiusOption.REJECT,
|
||||
RadiusOption.get_attributes('non_member_attributes', attributes_kwargs),
|
||||
u"Machine non active / adherent non cotisant",
|
||||
getattr(
|
||||
RadiusOption.get_cached_value("non_member_vlan"),
|
||||
"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
|
||||
# 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
|
||||
if not interface.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,
|
||||
DECISION_VLAN,
|
||||
True,
|
||||
attributes
|
||||
attributes,
|
||||
)
|
||||
else:
|
||||
return (
|
||||
sw_name,
|
||||
room,
|
||||
u'Machine OK' + extra_log,
|
||||
u"Machine OK" + extra_log,
|
||||
DECISION_VLAN,
|
||||
True,
|
||||
attributes
|
||||
attributes,
|
||||
)
|
||||
|
|
|
@ -38,11 +38,9 @@ def can_view(user):
|
|||
A couple (allowed, msg) where allowed is a boolean which is True if
|
||||
viewing is granted and msg is a message (can be None).
|
||||
"""
|
||||
can = user.has_module_perms('admin')
|
||||
can = user.has_module_perms("admin")
|
||||
return (
|
||||
can,
|
||||
None if can else _("You don't have the right to view this"
|
||||
" application."),
|
||||
'admin'
|
||||
None if can else _("You don't have the right to view this" " application."),
|
||||
"admin",
|
||||
)
|
||||
|
||||
|
|
|
@ -34,12 +34,14 @@ def classname(obj):
|
|||
""" Returns the object class name """
|
||||
return obj.__class__.__name__
|
||||
|
||||
|
||||
@register.filter
|
||||
def is_facture(baseinvoice):
|
||||
"""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):
|
||||
"""Creates the correct history button for an instance.
|
||||
|
||||
|
@ -51,9 +53,9 @@ def history_button(instance, text=False, html_class=True):
|
|||
|
||||
"""
|
||||
return {
|
||||
'application': instance._meta.app_label,
|
||||
'name': instance._meta.model_name,
|
||||
'id': instance.id,
|
||||
'text': text,
|
||||
'class': html_class,
|
||||
"application": instance._meta.app_label,
|
||||
"name": instance._meta.model_name,
|
||||
"id": instance.id,
|
||||
"text": text,
|
||||
"class": html_class,
|
||||
}
|
||||
|
|
24
logs/urls.py
24
logs/urls.py
|
@ -30,18 +30,20 @@ from django.conf.urls import url
|
|||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', views.index, name='index'),
|
||||
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(r"^$", views.index, name="index"),
|
||||
url(r"^stats_logs$", views.stats_logs, name="stats-logs"),
|
||||
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,
|
||||
name='history',
|
||||
name="history",
|
||||
),
|
||||
]
|
||||
|
|
453
logs/views.py
453
logs/views.py
|
@ -60,16 +60,9 @@ from users.models import (
|
|||
Ban,
|
||||
Whitelist,
|
||||
Adherent,
|
||||
Club
|
||||
)
|
||||
from cotisations.models import (
|
||||
Facture,
|
||||
Vente,
|
||||
Article,
|
||||
Banque,
|
||||
Paiement,
|
||||
Cotisation
|
||||
Club,
|
||||
)
|
||||
from cotisations.models import Facture, Vente, Article, Banque, Paiement, Cotisation
|
||||
from machines.models import (
|
||||
Machine,
|
||||
MachineType,
|
||||
|
@ -84,7 +77,7 @@ from machines.models import (
|
|||
Nas,
|
||||
SOA,
|
||||
Mx,
|
||||
Ns
|
||||
Ns,
|
||||
)
|
||||
from topologie.models import (
|
||||
Switch,
|
||||
|
@ -93,7 +86,7 @@ from topologie.models import (
|
|||
Stack,
|
||||
ModelSwitch,
|
||||
ConstructorSwitch,
|
||||
AccessPoint
|
||||
AccessPoint,
|
||||
)
|
||||
from preferences.models import GeneralOption
|
||||
from re2o.views import form
|
||||
|
@ -105,36 +98,24 @@ from re2o.utils import (
|
|||
all_active_assigned_interfaces_count,
|
||||
all_active_interfaces_count,
|
||||
)
|
||||
from re2o.base import (
|
||||
re2o_paginator,
|
||||
SortTable
|
||||
)
|
||||
from re2o.acl import (
|
||||
can_view_all,
|
||||
can_view_app,
|
||||
can_edit_history,
|
||||
)
|
||||
from re2o.base import re2o_paginator, SortTable
|
||||
from re2o.acl import can_view_all, can_view_app, can_edit_history
|
||||
|
||||
|
||||
@login_required
|
||||
@can_view_app('logs')
|
||||
@can_view_app("logs")
|
||||
def index(request):
|
||||
"""Affiche les logs affinés, date reformatées, selectionne
|
||||
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
|
||||
content_type_filter = ['ban', 'whitelist', 'vente', 'interface', 'user']
|
||||
content_type_filter = ["ban", "whitelist", "vente", "interface", "user"]
|
||||
# Select only wanted versions
|
||||
versions = Version.objects.filter(
|
||||
content_type__in=ContentType.objects.filter(
|
||||
model__in=content_type_filter
|
||||
)
|
||||
).select_related('revision')
|
||||
content_type__in=ContentType.objects.filter(model__in=content_type_filter)
|
||||
).select_related("revision")
|
||||
versions = SortTable.sort(
|
||||
versions,
|
||||
request.GET.get('col'),
|
||||
request.GET.get('order'),
|
||||
SortTable.LOGS_INDEX
|
||||
versions, request.GET.get("col"), request.GET.get("order"), SortTable.LOGS_INDEX
|
||||
)
|
||||
versions = re2o_paginator(request, versions, pagination_number)
|
||||
# Force to have a list instead of QuerySet
|
||||
|
@ -146,20 +127,21 @@ def index(request):
|
|||
if versions.object_list[i].object:
|
||||
version = versions.object_list[i]
|
||||
versions.object_list[i] = {
|
||||
'rev_id': version.revision.id,
|
||||
'comment': version.revision.comment,
|
||||
'datetime': version.revision.date_created,
|
||||
'username':
|
||||
version.revision.user.get_username()
|
||||
if version.revision.user else '?',
|
||||
'user_id': version.revision.user_id,
|
||||
'version': version}
|
||||
"rev_id": version.revision.id,
|
||||
"comment": version.revision.comment,
|
||||
"datetime": version.revision.date_created,
|
||||
"username": version.revision.user.get_username()
|
||||
if version.revision.user
|
||||
else "?",
|
||||
"user_id": version.revision.user_id,
|
||||
"version": version,
|
||||
}
|
||||
else:
|
||||
to_remove.insert(0, i)
|
||||
# Remove all tagged invalid items
|
||||
for i in to_remove:
|
||||
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
|
||||
|
@ -167,19 +149,20 @@ def index(request):
|
|||
def stats_logs(request):
|
||||
"""Affiche l'ensemble des logs et des modifications sur les objets,
|
||||
classés par date croissante, en vrac"""
|
||||
pagination_number = GeneralOption.get_cached_value('pagination_number')
|
||||
revisions = Revision.objects.all().select_related('user')\
|
||||
.prefetch_related('version_set__object')
|
||||
pagination_number = GeneralOption.get_cached_value("pagination_number")
|
||||
revisions = (
|
||||
Revision.objects.all()
|
||||
.select_related("user")
|
||||
.prefetch_related("version_set__object")
|
||||
)
|
||||
revisions = SortTable.sort(
|
||||
revisions,
|
||||
request.GET.get('col'),
|
||||
request.GET.get('order'),
|
||||
SortTable.LOGS_STATS_LOGS
|
||||
request.GET.get("col"),
|
||||
request.GET.get("order"),
|
||||
SortTable.LOGS_STATS_LOGS,
|
||||
)
|
||||
revisions = re2o_paginator(request, revisions, pagination_number)
|
||||
return render(request, 'logs/stats_logs.html', {
|
||||
'revisions_list': revisions
|
||||
})
|
||||
return render(request, "logs/stats_logs.html", {"revisions_list": revisions})
|
||||
|
||||
|
||||
@login_required
|
||||
|
@ -193,11 +176,12 @@ def revert_action(request, revision_id):
|
|||
if request.method == "POST":
|
||||
revision.revert()
|
||||
messages.success(request, _("The action was deleted."))
|
||||
return redirect(reverse('logs:index'))
|
||||
return form({
|
||||
'objet': revision,
|
||||
'objet_name': revision.__class__.__name__
|
||||
}, 'logs/delete.html', request)
|
||||
return redirect(reverse("logs:index"))
|
||||
return form(
|
||||
{"objet": revision, "objet_name": revision.__class__.__name__},
|
||||
"logs/delete.html",
|
||||
request,
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
|
@ -207,226 +191,221 @@ def stats_general(request):
|
|||
range, et les statistiques générales sur les users : users actifs,
|
||||
cotisants, activés, archivés, etc"""
|
||||
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)
|
||||
used_ip = Interface.objects.filter(ipv4__in=all_ip).count()
|
||||
active_ip = all_active_assigned_interfaces_count().filter(
|
||||
ipv4__in=IpList.objects.filter(ip_type=ip_range)
|
||||
).count()
|
||||
ip_dict[ip_range] = [ip_range, ip_range.vlan, all_ip.count(),
|
||||
used_ip, active_ip, all_ip.count()-used_ip]
|
||||
active_ip = (
|
||||
all_active_assigned_interfaces_count()
|
||||
.filter(ipv4__in=IpList.objects.filter(ip_type=ip_range))
|
||||
.count()
|
||||
)
|
||||
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_has_access = all_has_access(including_asso=False)
|
||||
_all_baned = all_baned()
|
||||
_all_whitelisted = all_whitelisted()
|
||||
_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 = [
|
||||
[ # First set of data (about users)
|
||||
[ # Headers
|
||||
[ # First set of data (about users)
|
||||
[ # Headers
|
||||
_("Category"),
|
||||
_("Number of users (members and clubs)"),
|
||||
_("Number of members"),
|
||||
_("Number of clubs")
|
||||
_("Number of clubs"),
|
||||
],
|
||||
{ # Data
|
||||
'active_users': [
|
||||
{ # Data
|
||||
"active_users": [
|
||||
_("Activated users"),
|
||||
User.objects.filter(state=User.STATE_ACTIVE).count(),
|
||||
(Adherent.objects
|
||||
.filter(state=Adherent.STATE_ACTIVE)
|
||||
.count()),
|
||||
Club.objects.filter(state=Club.STATE_ACTIVE).count()
|
||||
(Adherent.objects.filter(state=Adherent.STATE_ACTIVE).count()),
|
||||
Club.objects.filter(state=Club.STATE_ACTIVE).count(),
|
||||
],
|
||||
'inactive_users': [
|
||||
"inactive_users": [
|
||||
_("Disabled users"),
|
||||
User.objects.filter(state=User.STATE_DISABLED).count(),
|
||||
(Adherent.objects
|
||||
.filter(state=Adherent.STATE_DISABLED)
|
||||
.count()),
|
||||
Club.objects.filter(state=Club.STATE_DISABLED).count()
|
||||
(Adherent.objects.filter(state=Adherent.STATE_DISABLED).count()),
|
||||
Club.objects.filter(state=Club.STATE_DISABLED).count(),
|
||||
],
|
||||
'archive_users': [
|
||||
"archive_users": [
|
||||
_("Archived users"),
|
||||
User.objects.filter(state=User.STATE_ARCHIVE).count(),
|
||||
(Adherent.objects
|
||||
.filter(state=Adherent.STATE_ARCHIVE)
|
||||
.count()),
|
||||
Club.objects.filter(state=Club.STATE_ARCHIVE).count()
|
||||
(Adherent.objects.filter(state=Adherent.STATE_ARCHIVE).count()),
|
||||
Club.objects.filter(state=Club.STATE_ARCHIVE).count(),
|
||||
],
|
||||
'full_archive_users': [
|
||||
"full_archive_users": [
|
||||
_("Full Archived users"),
|
||||
User.objects.filter(state=User.STATE_FULL_ARCHIVE).count(),
|
||||
(Adherent.objects
|
||||
.filter(state=Adherent.STATE_FULL_ARCHIVE)
|
||||
.count()),
|
||||
Club.objects.filter(state=Club.STATE_FULL_ARCHIVE).count()
|
||||
(
|
||||
Adherent.objects.filter(
|
||||
state=Adherent.STATE_FULL_ARCHIVE
|
||||
).count()
|
||||
),
|
||||
Club.objects.filter(state=Club.STATE_FULL_ARCHIVE).count(),
|
||||
],
|
||||
'not_active_users': [
|
||||
"not_active_users": [
|
||||
_("Not yet active users"),
|
||||
User.objects.filter(state=User.STATE_NOT_YET_ACTIVE).count(),
|
||||
(Adherent.objects
|
||||
.filter(state=Adherent.STATE_NOT_YET_ACTIVE)
|
||||
.count()),
|
||||
Club.objects.filter(state=Club.STATE_NOT_YET_ACTIVE).count()
|
||||
(
|
||||
Adherent.objects.filter(
|
||||
state=Adherent.STATE_NOT_YET_ACTIVE
|
||||
).count()
|
||||
),
|
||||
Club.objects.filter(state=Club.STATE_NOT_YET_ACTIVE).count(),
|
||||
],
|
||||
'adherent_users': [
|
||||
"adherent_users": [
|
||||
_("Contributing members"),
|
||||
_all_adherent.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"),
|
||||
_all_has_access.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"),
|
||||
_all_baned.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"),
|
||||
_all_whitelisted.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)"),
|
||||
_all_active_interfaces_count.count(),
|
||||
(_all_active_interfaces_count
|
||||
.exclude(machine__user__adherent__isnull=True)
|
||||
.count()),
|
||||
(_all_active_interfaces_count
|
||||
.exclude(machine__user__club__isnull=True)
|
||||
.count())
|
||||
(
|
||||
_all_active_interfaces_count.exclude(
|
||||
machine__user__adherent__isnull=True
|
||||
).count()
|
||||
),
|
||||
(
|
||||
_all_active_interfaces_count.exclude(
|
||||
machine__user__club__isnull=True
|
||||
).count()
|
||||
),
|
||||
],
|
||||
'actives_assigned_interfaces': [
|
||||
"actives_assigned_interfaces": [
|
||||
_("Active interfaces assigned IPv4"),
|
||||
_all_active_assigned_interfaces_count.count(),
|
||||
(_all_active_assigned_interfaces_count
|
||||
.exclude(machine__user__adherent__isnull=True)
|
||||
.count()),
|
||||
(_all_active_assigned_interfaces_count
|
||||
.exclude(machine__user__club__isnull=True)
|
||||
.count())
|
||||
]
|
||||
}
|
||||
(
|
||||
_all_active_assigned_interfaces_count.exclude(
|
||||
machine__user__adherent__isnull=True
|
||||
).count()
|
||||
),
|
||||
(
|
||||
_all_active_assigned_interfaces_count.exclude(
|
||||
machine__user__club__isnull=True
|
||||
).count()
|
||||
),
|
||||
],
|
||||
},
|
||||
],
|
||||
[ # Second set of data (about ip adresses)
|
||||
[ # Headers
|
||||
[ # Second set of data (about ip adresses)
|
||||
[ # Headers
|
||||
_("IP range"),
|
||||
_("VLAN"),
|
||||
_("Total number of IP addresses"),
|
||||
_("Number of assigned IP addresses"),
|
||||
_("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
|
||||
@can_view_app('users', 'cotisations', 'machines', 'topologie')
|
||||
@can_view_app("users", "cotisations", "machines", "topologie")
|
||||
def stats_models(request):
|
||||
"""Statistiques générales, affiche les comptages par models:
|
||||
nombre d'users, d'écoles, de droits, de bannissements,
|
||||
de factures, de ventes, de banque, de machines, etc"""
|
||||
stats = {
|
||||
_("Users"): {
|
||||
'users': [User._meta.verbose_name, User.objects.count()],
|
||||
'adherents': [Adherent._meta.verbose_name, Adherent.objects.count()],
|
||||
'clubs': [Club._meta.verbose_name, Club.objects.count()],
|
||||
'serviceuser': [ServiceUser._meta.verbose_name,
|
||||
ServiceUser.objects.count()],
|
||||
'school': [School._meta.verbose_name, School.objects.count()],
|
||||
'listright': [ListRight._meta.verbose_name, ListRight.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()]
|
||||
"users": [User._meta.verbose_name, User.objects.count()],
|
||||
"adherents": [Adherent._meta.verbose_name, Adherent.objects.count()],
|
||||
"clubs": [Club._meta.verbose_name, Club.objects.count()],
|
||||
"serviceuser": [
|
||||
ServiceUser._meta.verbose_name,
|
||||
ServiceUser.objects.count(),
|
||||
],
|
||||
"school": [School._meta.verbose_name, School.objects.count()],
|
||||
"listright": [ListRight._meta.verbose_name, ListRight.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"): {
|
||||
'factures': [
|
||||
Facture._meta.verbose_name,
|
||||
Facture.objects.count()
|
||||
],
|
||||
'vente': [
|
||||
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()
|
||||
],
|
||||
"factures": [Facture._meta.verbose_name, Facture.objects.count()],
|
||||
"vente": [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"): {
|
||||
'machine': [Machine._meta.verbose_name,
|
||||
Machine.objects.count()],
|
||||
'typemachine': [MachineType._meta.verbose_name,
|
||||
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()
|
||||
"machine": [Machine._meta.verbose_name, Machine.objects.count()],
|
||||
"typemachine": [
|
||||
MachineType._meta.verbose_name,
|
||||
MachineType.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()],
|
||||
"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()],
|
||||
"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"): {
|
||||
'switch': [Switch._meta.verbose_name,
|
||||
Switch.objects.count()],
|
||||
'bornes': [AccessPoint._meta.verbose_name,
|
||||
AccessPoint.objects.count()],
|
||||
'port': [Port._meta.verbose_name, Port.objects.count()],
|
||||
'chambre': [Room._meta.verbose_name, Room.objects.count()],
|
||||
'stack': [Stack._meta.verbose_name, Stack.objects.count()],
|
||||
'modelswitch': [
|
||||
"switch": [Switch._meta.verbose_name, Switch.objects.count()],
|
||||
"bornes": [AccessPoint._meta.verbose_name, AccessPoint.objects.count()],
|
||||
"port": [Port._meta.verbose_name, Port.objects.count()],
|
||||
"chambre": [Room._meta.verbose_name, Room.objects.count()],
|
||||
"stack": [Stack._meta.verbose_name, Stack.objects.count()],
|
||||
"modelswitch": [
|
||||
ModelSwitch._meta.verbose_name,
|
||||
ModelSwitch.objects.count()
|
||||
ModelSwitch.objects.count(),
|
||||
],
|
||||
'constructorswitch': [
|
||||
"constructorswitch": [
|
||||
ConstructorSwitch._meta.verbose_name,
|
||||
ConstructorSwitch.objects.count()
|
||||
ConstructorSwitch.objects.count(),
|
||||
],
|
||||
},
|
||||
_("Actions performed"):
|
||||
{
|
||||
'revision': [_("Number of actions"), Revision.objects.count()],
|
||||
_("Actions performed"): {
|
||||
"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
|
||||
@can_view_app('users')
|
||||
@can_view_app("users")
|
||||
def stats_users(request):
|
||||
"""Affiche les statistiques base de données aggrégées par user :
|
||||
nombre de machines par user, d'etablissements par user,
|
||||
|
@ -434,55 +413,51 @@ def stats_users(request):
|
|||
de bannissement par user, etc"""
|
||||
stats = {
|
||||
_("User"): {
|
||||
_("Machines"): User.objects.annotate(
|
||||
num=Count('machine')
|
||||
).order_by('-num')[:10],
|
||||
_("Invoice"): User.objects.annotate(
|
||||
num=Count('facture')
|
||||
).order_by('-num')[:10],
|
||||
_("Ban"): User.objects.annotate(
|
||||
num=Count('ban')
|
||||
).order_by('-num')[:10],
|
||||
_("Whitelist"): User.objects.annotate(
|
||||
num=Count('whitelist')
|
||||
).order_by('-num')[:10],
|
||||
_("Rights"): User.objects.annotate(
|
||||
num=Count('groups')
|
||||
).order_by('-num')[:10],
|
||||
_("Machines"): User.objects.annotate(num=Count("machine")).order_by("-num")[
|
||||
:10
|
||||
],
|
||||
_("Invoice"): User.objects.annotate(num=Count("facture")).order_by("-num")[
|
||||
:10
|
||||
],
|
||||
_("Ban"): User.objects.annotate(num=Count("ban")).order_by("-num")[:10],
|
||||
_("Whitelist"): User.objects.annotate(num=Count("whitelist")).order_by(
|
||||
"-num"
|
||||
)[:10],
|
||||
_("Rights"): User.objects.annotate(num=Count("groups")).order_by("-num")[
|
||||
:10
|
||||
],
|
||||
},
|
||||
_("School"): {
|
||||
_("User"): School.objects.annotate(
|
||||
num=Count('user')
|
||||
).order_by('-num')[:10],
|
||||
_("User"): School.objects.annotate(num=Count("user")).order_by("-num")[:10]
|
||||
},
|
||||
_("Payment method"): {
|
||||
_("User"): Paiement.objects.annotate(
|
||||
num=Count('facture')
|
||||
).order_by('-num')[:10],
|
||||
_("User"): Paiement.objects.annotate(num=Count("facture")).order_by("-num")[
|
||||
:10
|
||||
]
|
||||
},
|
||||
_("Bank"): {
|
||||
_("User"): Banque.objects.annotate(
|
||||
num=Count('facture')
|
||||
).order_by('-num')[:10],
|
||||
_("User"): Banque.objects.annotate(num=Count("facture")).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
|
||||
@can_view_app('users')
|
||||
@can_view_app("users")
|
||||
def stats_actions(request):
|
||||
"""Vue qui affiche les statistiques de modifications d'objets par
|
||||
utilisateurs.
|
||||
Affiche le nombre de modifications aggrégées par utilisateurs"""
|
||||
stats = {
|
||||
_("User"): {
|
||||
_("Action"): User.objects.annotate(
|
||||
num=Count('revision')
|
||||
).order_by('-num')[:40],
|
||||
},
|
||||
_("Action"): User.objects.annotate(num=Count("revision")).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):
|
||||
|
@ -509,33 +484,29 @@ def history(request, application, object_name, object_id):
|
|||
model = apps.get_model(application, object_name)
|
||||
except LookupError:
|
||||
raise Http404(_("No model found."))
|
||||
object_name_id = object_name + 'id'
|
||||
object_name_id = object_name + "id"
|
||||
kwargs = {object_name_id: object_id}
|
||||
try:
|
||||
instance = model.get_instance(**kwargs)
|
||||
except model.DoesNotExist:
|
||||
messages.error(request, _("Nonexistent entry."))
|
||||
return redirect(reverse(
|
||||
'users:profil',
|
||||
kwargs={'userid': str(request.user.id)}
|
||||
))
|
||||
return redirect(
|
||||
reverse("users:profil", kwargs={"userid": str(request.user.id)})
|
||||
)
|
||||
can, msg, _permissions = instance.can_view(request.user)
|
||||
if not can:
|
||||
messages.error(request, msg or _("You don't have the right to access this menu."))
|
||||
return redirect(reverse(
|
||||
'users:profil',
|
||||
kwargs={'userid': str(request.user.id)}
|
||||
))
|
||||
pagination_number = GeneralOption.get_cached_value('pagination_number')
|
||||
messages.error(
|
||||
request, msg or _("You don't have the right to access this menu.")
|
||||
)
|
||||
return redirect(
|
||||
reverse("users:profil", kwargs={"userid": str(request.user.id)})
|
||||
)
|
||||
pagination_number = GeneralOption.get_cached_value("pagination_number")
|
||||
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()):
|
||||
reversions = (reversions |
|
||||
Version.objects.get_for_object(related_object))
|
||||
reversions = reversions | Version.objects.get_for_object(related_object)
|
||||
reversions = re2o_paginator(request, reversions, pagination_number)
|
||||
return render(
|
||||
request,
|
||||
're2o/history.html',
|
||||
{'reversions': reversions, 'object': instance}
|
||||
request, "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
|
||||
viewing is granted and msg is a message (can be None).
|
||||
"""
|
||||
can = user.has_module_perms('machines')
|
||||
can = user.has_module_perms("machines")
|
||||
return (
|
||||
can,
|
||||
None if can else _("You don't have the right to view this"
|
||||
" application."),
|
||||
('machines',)
|
||||
None if can else _("You don't have the right to view this" " application."),
|
||||
("machines",),
|
||||
)
|
||||
|
||||
|
|
|
@ -51,106 +51,127 @@ from .models import IpType, Machine, MachineType, Domain, IpList, Interface
|
|||
|
||||
class MachineAdmin(VersionAdmin):
|
||||
""" Admin view of a Machine object """
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class Ipv6ListAdmin(VersionAdmin):
|
||||
""" Admin view of a Ipv6List object """
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class IpTypeAdmin(VersionAdmin):
|
||||
""" Admin view of a IpType object """
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class MachineTypeAdmin(VersionAdmin):
|
||||
""" Admin view of a MachineType object """
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class VlanAdmin(VersionAdmin):
|
||||
""" Admin view of a Vlan object """
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class ExtensionAdmin(VersionAdmin):
|
||||
""" Admin view of a Extension object """
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class SOAAdmin(VersionAdmin):
|
||||
""" Admin view of a SOA object """
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class MxAdmin(VersionAdmin):
|
||||
""" Admin view of a MX object """
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class NsAdmin(VersionAdmin):
|
||||
""" Admin view of a NS object """
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class TxtAdmin(VersionAdmin):
|
||||
""" Admin view of a TXT object """
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class DNameAdmin(VersionAdmin):
|
||||
""" Admin view of a DName object """
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class SrvAdmin(VersionAdmin):
|
||||
""" Admin view of a SRV object """
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class SshFpAdmin(VersionAdmin):
|
||||
""" Admin view of a SSHFP object """
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class NasAdmin(VersionAdmin):
|
||||
""" Admin view of a Nas object """
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class IpListAdmin(VersionAdmin):
|
||||
""" Admin view of a Ipv4List object """
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class OuverturePortAdmin(VersionAdmin):
|
||||
""" Admin view of a OuverturePort object """
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class OuverturePortListAdmin(VersionAdmin):
|
||||
""" Admin view of a OuverturePortList object """
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class InterfaceAdmin(VersionAdmin):
|
||||
""" 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):
|
||||
""" Admin view of a Domain object """
|
||||
list_display = ('interface_parent', 'name', 'extension', 'cname')
|
||||
|
||||
list_display = ("interface_parent", "name", "extension", "cname")
|
||||
|
||||
|
||||
class ServiceAdmin(VersionAdmin):
|
||||
""" 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):
|
||||
""" Admin view of a RoleAdmin object """
|
||||
|
||||
pass
|
||||
|
||||
|
||||
|
|
|
@ -70,19 +70,19 @@ class EditMachineForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = Machine
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
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)
|
||||
self.fields['name'].label = _("Machine name")
|
||||
self.fields["name"].label = _("Machine name")
|
||||
|
||||
|
||||
class NewMachineForm(EditMachineForm):
|
||||
"""Creation d'une machine, ne renseigne que le nom"""
|
||||
|
||||
class Meta(EditMachineForm.Meta):
|
||||
fields = ['name']
|
||||
fields = ["name"]
|
||||
|
||||
|
||||
class EditInterfaceForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
||||
|
@ -90,39 +90,38 @@ class EditInterfaceForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = Interface
|
||||
fields = ['machine', 'machine_type', 'ipv4', 'mac_address', 'details']
|
||||
fields = ["machine", "machine_type", "ipv4", "mac_address", "details"]
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
||||
user = kwargs.get('user')
|
||||
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||
user = kwargs.get("user")
|
||||
super(EditInterfaceForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||
self.fields['mac_address'].label = _("MAC address")
|
||||
self.fields['machine_type'].label = _("Machine type")
|
||||
self.fields['machine_type'].empty_label = _("Select a machine type")
|
||||
self.fields["mac_address"].label = _("MAC address")
|
||||
self.fields["machine_type"].label = _("Machine type")
|
||||
self.fields["machine_type"].empty_label = _("Select a machine type")
|
||||
if "ipv4" in self.fields:
|
||||
self.fields['ipv4'].empty_label = _("Automatic IPv4 assignment")
|
||||
self.fields['ipv4'].queryset = IpList.objects.filter(
|
||||
interface__isnull=True
|
||||
)
|
||||
self.fields["ipv4"].empty_label = _("Automatic IPv4 assignment")
|
||||
self.fields["ipv4"].queryset = IpList.objects.filter(interface__isnull=True)
|
||||
can_use_all_iptype, _reason, _permissions = IpType.can_use_all(user)
|
||||
if not can_use_all_iptype:
|
||||
self.fields['ipv4'].queryset = IpList.objects.filter(
|
||||
self.fields["ipv4"].queryset = IpList.objects.filter(
|
||||
interface__isnull=True
|
||||
).filter(ip_type__in=IpType.objects.filter(need_infra=False))
|
||||
else:
|
||||
self.fields['ipv4'].queryset = IpList.objects.filter(
|
||||
self.fields["ipv4"].queryset = IpList.objects.filter(
|
||||
interface__isnull=True
|
||||
)
|
||||
# Add it's own address
|
||||
self.fields['ipv4'].queryset |= IpList.objects.filter(
|
||||
self.fields["ipv4"].queryset |= IpList.objects.filter(
|
||||
interface=self.instance
|
||||
)
|
||||
if "machine" in self.fields:
|
||||
self.fields['machine'].queryset = Machine.objects.all() \
|
||||
.select_related('user')
|
||||
self.fields["machine"].queryset = Machine.objects.all().select_related(
|
||||
"user"
|
||||
)
|
||||
can_use_all_machinetype, _reason, _permissions = MachineType.can_use_all(user)
|
||||
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)
|
||||
)
|
||||
|
||||
|
@ -132,7 +131,7 @@ class AddInterfaceForm(EditInterfaceForm):
|
|||
affiche ou non l'ensemble des ip disponibles"""
|
||||
|
||||
class Meta(EditInterfaceForm.Meta):
|
||||
fields = ['machine_type', 'ipv4', 'mac_address', 'details']
|
||||
fields = ["machine_type", "ipv4", "mac_address", "details"]
|
||||
|
||||
|
||||
class AliasForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
||||
|
@ -140,15 +139,15 @@ class AliasForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = Domain
|
||||
fields = ['name', 'extension', 'ttl']
|
||||
fields = ["name", "extension", "ttl"]
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
||||
user = kwargs['user']
|
||||
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||
user = kwargs["user"]
|
||||
super(AliasForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||
can_use_all, _reason, _permissions = Extension.can_use_all(user)
|
||||
if not can_use_all:
|
||||
self.fields['extension'].queryset = Extension.objects.filter(
|
||||
self.fields["extension"].queryset = Extension.objects.filter(
|
||||
need_infra=False
|
||||
)
|
||||
|
||||
|
@ -158,30 +157,31 @@ class DomainForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = Domain
|
||||
fields = ['name', 'ttl']
|
||||
fields = ["name", "ttl"]
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
if 'user' in kwargs:
|
||||
user = kwargs['user']
|
||||
initial = kwargs.get('initial', {})
|
||||
initial['name'] = user.get_next_domain_name()
|
||||
kwargs['initial'] = initial
|
||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
||||
if "user" in kwargs:
|
||||
user = kwargs["user"]
|
||||
initial = kwargs.get("initial", {})
|
||||
initial["name"] = user.get_next_domain_name()
|
||||
kwargs["initial"] = initial
|
||||
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||
super(DomainForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||
|
||||
|
||||
class DelAliasForm(FormRevMixin, Form):
|
||||
"""Suppression d'un ou plusieurs objets alias"""
|
||||
|
||||
alias = forms.ModelMultipleChoiceField(
|
||||
queryset=Domain.objects.all(),
|
||||
label=_("Current aliases"),
|
||||
widget=forms.CheckboxSelectMultiple
|
||||
widget=forms.CheckboxSelectMultiple,
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
interface = kwargs.pop('interface')
|
||||
interface = kwargs.pop("interface")
|
||||
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)
|
||||
)
|
||||
|
||||
|
@ -191,30 +191,31 @@ class MachineTypeForm(FormRevMixin, ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = MachineType
|
||||
fields = ['name', 'ip_type']
|
||||
fields = ["name", "ip_type"]
|
||||
|
||||
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)
|
||||
self.fields['name'].label = _("Machine type to add")
|
||||
self.fields['ip_type'].label = _("Related IP type")
|
||||
self.fields["name"].label = _("Machine type to add")
|
||||
self.fields["ip_type"].label = _("Related IP type")
|
||||
|
||||
|
||||
class DelMachineTypeForm(FormRevMixin, Form):
|
||||
"""Suppression d'un ou plusieurs machinetype"""
|
||||
|
||||
machinetypes = forms.ModelMultipleChoiceField(
|
||||
queryset=MachineType.objects.none(),
|
||||
label=_("Current machine types"),
|
||||
widget=forms.CheckboxSelectMultiple
|
||||
widget=forms.CheckboxSelectMultiple,
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
instances = kwargs.pop('instances', None)
|
||||
instances = kwargs.pop("instances", None)
|
||||
super(DelMachineTypeForm, self).__init__(*args, **kwargs)
|
||||
if instances:
|
||||
self.fields['machinetypes'].queryset = instances
|
||||
self.fields["machinetypes"].queryset = instances
|
||||
else:
|
||||
self.fields['machinetypes'].queryset = MachineType.objects.all()
|
||||
self.fields["machinetypes"].queryset = MachineType.objects.all()
|
||||
|
||||
|
||||
class IpTypeForm(FormRevMixin, ModelForm):
|
||||
|
@ -223,12 +224,12 @@ class IpTypeForm(FormRevMixin, ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = IpType
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
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)
|
||||
self.fields['name'].label = _("IP type to add")
|
||||
self.fields["name"].label = _("IP type to add")
|
||||
|
||||
|
||||
class EditIpTypeForm(IpTypeForm):
|
||||
|
@ -236,27 +237,37 @@ class EditIpTypeForm(IpTypeForm):
|
|||
synchroniser les objets iplist"""
|
||||
|
||||
class Meta(IpTypeForm.Meta):
|
||||
fields = ['extension', 'name', 'need_infra', 'domaine_ip_network', 'domaine_ip_netmask',
|
||||
'prefix_v6', 'prefix_v6_length',
|
||||
'vlan', 'reverse_v4', 'reverse_v6',
|
||||
'ouverture_ports']
|
||||
fields = [
|
||||
"extension",
|
||||
"name",
|
||||
"need_infra",
|
||||
"domaine_ip_network",
|
||||
"domaine_ip_netmask",
|
||||
"prefix_v6",
|
||||
"prefix_v6_length",
|
||||
"vlan",
|
||||
"reverse_v4",
|
||||
"reverse_v6",
|
||||
"ouverture_ports",
|
||||
]
|
||||
|
||||
|
||||
class DelIpTypeForm(FormRevMixin, Form):
|
||||
"""Suppression d'un ou plusieurs iptype"""
|
||||
|
||||
iptypes = forms.ModelMultipleChoiceField(
|
||||
queryset=IpType.objects.none(),
|
||||
label=_("Current IP types"),
|
||||
widget=forms.CheckboxSelectMultiple
|
||||
widget=forms.CheckboxSelectMultiple,
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
instances = kwargs.pop('instances', None)
|
||||
instances = kwargs.pop("instances", None)
|
||||
super(DelIpTypeForm, self).__init__(*args, **kwargs)
|
||||
if instances:
|
||||
self.fields['iptypes'].queryset = instances
|
||||
self.fields["iptypes"].queryset = instances
|
||||
else:
|
||||
self.fields['iptypes'].queryset = IpType.objects.all()
|
||||
self.fields["iptypes"].queryset = IpType.objects.all()
|
||||
|
||||
|
||||
class ExtensionForm(FormRevMixin, ModelForm):
|
||||
|
@ -264,33 +275,34 @@ class ExtensionForm(FormRevMixin, ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = Extension
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
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)
|
||||
self.fields['name'].label = _("Extension to add")
|
||||
self.fields['origin'].label = _("A record origin")
|
||||
self.fields['origin_v6'].label = _("AAAA record origin")
|
||||
self.fields['soa'].label = _("SOA record to use")
|
||||
self.fields['dnssec'].label = _("Sign with DNSSEC")
|
||||
self.fields["name"].label = _("Extension to add")
|
||||
self.fields["origin"].label = _("A record origin")
|
||||
self.fields["origin_v6"].label = _("AAAA record origin")
|
||||
self.fields["soa"].label = _("SOA record to use")
|
||||
self.fields["dnssec"].label = _("Sign with DNSSEC")
|
||||
|
||||
|
||||
class DelExtensionForm(FormRevMixin, Form):
|
||||
"""Suppression d'une ou plusieurs extensions"""
|
||||
|
||||
extensions = forms.ModelMultipleChoiceField(
|
||||
queryset=Extension.objects.none(),
|
||||
label=_("Current extensions"),
|
||||
widget=forms.CheckboxSelectMultiple
|
||||
widget=forms.CheckboxSelectMultiple,
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
instances = kwargs.pop('instances', None)
|
||||
instances = kwargs.pop("instances", None)
|
||||
super(DelExtensionForm, self).__init__(*args, **kwargs)
|
||||
if instances:
|
||||
self.fields['extensions'].queryset = instances
|
||||
self.fields["extensions"].queryset = instances
|
||||
else:
|
||||
self.fields['extensions'].queryset = Extension.objects.all()
|
||||
self.fields["extensions"].queryset = Extension.objects.all()
|
||||
|
||||
|
||||
class Ipv6ListForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
||||
|
@ -298,10 +310,10 @@ class Ipv6ListForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = Ipv6List
|
||||
fields = ['ipv6', 'slaac_ip']
|
||||
fields = ["ipv6", "slaac_ip"]
|
||||
|
||||
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)
|
||||
|
||||
|
||||
|
@ -310,28 +322,29 @@ class SOAForm(FormRevMixin, ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = SOA
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
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)
|
||||
|
||||
|
||||
class DelSOAForm(FormRevMixin, Form):
|
||||
"""Suppression d'un ou plusieurs SOA"""
|
||||
|
||||
soa = forms.ModelMultipleChoiceField(
|
||||
queryset=SOA.objects.none(),
|
||||
label=_("Current SOA records"),
|
||||
widget=forms.CheckboxSelectMultiple
|
||||
widget=forms.CheckboxSelectMultiple,
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
instances = kwargs.pop('instances', None)
|
||||
instances = kwargs.pop("instances", None)
|
||||
super(DelSOAForm, self).__init__(*args, **kwargs)
|
||||
if instances:
|
||||
self.fields['soa'].queryset = instances
|
||||
self.fields["soa"].queryset = instances
|
||||
else:
|
||||
self.fields['soa'].queryset = SOA.objects.all()
|
||||
self.fields["soa"].queryset = SOA.objects.all()
|
||||
|
||||
|
||||
class MxForm(FormRevMixin, ModelForm):
|
||||
|
@ -339,31 +352,32 @@ class MxForm(FormRevMixin, ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = Mx
|
||||
fields = ['zone', 'priority', 'name', 'ttl']
|
||||
fields = ["zone", "priority", "name", "ttl"]
|
||||
|
||||
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)
|
||||
self.fields['name'].queryset = Domain.objects.exclude(
|
||||
self.fields["name"].queryset = Domain.objects.exclude(
|
||||
interface_parent=None
|
||||
).select_related('extension')
|
||||
).select_related("extension")
|
||||
|
||||
|
||||
class DelMxForm(FormRevMixin, Form):
|
||||
"""Suppression d'un ou plusieurs MX"""
|
||||
|
||||
mx = forms.ModelMultipleChoiceField(
|
||||
queryset=Mx.objects.none(),
|
||||
label=_("Current MX records"),
|
||||
widget=forms.CheckboxSelectMultiple
|
||||
widget=forms.CheckboxSelectMultiple,
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
instances = kwargs.pop('instances', None)
|
||||
instances = kwargs.pop("instances", None)
|
||||
super(DelMxForm, self).__init__(*args, **kwargs)
|
||||
if instances:
|
||||
self.fields['mx'].queryset = instances
|
||||
self.fields["mx"].queryset = instances
|
||||
else:
|
||||
self.fields['mx'].queryset = Mx.objects.all()
|
||||
self.fields["mx"].queryset = Mx.objects.all()
|
||||
|
||||
|
||||
class NsForm(FormRevMixin, ModelForm):
|
||||
|
@ -373,31 +387,32 @@ class NsForm(FormRevMixin, ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = Ns
|
||||
fields = ['zone', 'ns', 'ttl']
|
||||
fields = ["zone", "ns", "ttl"]
|
||||
|
||||
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)
|
||||
self.fields['ns'].queryset = Domain.objects.exclude(
|
||||
self.fields["ns"].queryset = Domain.objects.exclude(
|
||||
interface_parent=None
|
||||
).select_related('extension')
|
||||
).select_related("extension")
|
||||
|
||||
|
||||
class DelNsForm(FormRevMixin, Form):
|
||||
"""Suppresion d'un ou plusieurs NS"""
|
||||
|
||||
ns = forms.ModelMultipleChoiceField(
|
||||
queryset=Ns.objects.none(),
|
||||
label=_("Current NS records"),
|
||||
widget=forms.CheckboxSelectMultiple
|
||||
widget=forms.CheckboxSelectMultiple,
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
instances = kwargs.pop('instances', None)
|
||||
instances = kwargs.pop("instances", None)
|
||||
super(DelNsForm, self).__init__(*args, **kwargs)
|
||||
if instances:
|
||||
self.fields['ns'].queryset = instances
|
||||
self.fields["ns"].queryset = instances
|
||||
else:
|
||||
self.fields['ns'].queryset = Ns.objects.all()
|
||||
self.fields["ns"].queryset = Ns.objects.all()
|
||||
|
||||
|
||||
class TxtForm(FormRevMixin, ModelForm):
|
||||
|
@ -405,28 +420,29 @@ class TxtForm(FormRevMixin, ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = Txt
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
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)
|
||||
|
||||
|
||||
class DelTxtForm(FormRevMixin, Form):
|
||||
"""Suppression d'un ou plusieurs TXT"""
|
||||
|
||||
txt = forms.ModelMultipleChoiceField(
|
||||
queryset=Txt.objects.none(),
|
||||
label=_("Current TXT records"),
|
||||
widget=forms.CheckboxSelectMultiple
|
||||
widget=forms.CheckboxSelectMultiple,
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
instances = kwargs.pop('instances', None)
|
||||
instances = kwargs.pop("instances", None)
|
||||
super(DelTxtForm, self).__init__(*args, **kwargs)
|
||||
if instances:
|
||||
self.fields['txt'].queryset = instances
|
||||
self.fields["txt"].queryset = instances
|
||||
else:
|
||||
self.fields['txt'].queryset = Txt.objects.all()
|
||||
self.fields["txt"].queryset = Txt.objects.all()
|
||||
|
||||
|
||||
class DNameForm(FormRevMixin, ModelForm):
|
||||
|
@ -434,28 +450,29 @@ class DNameForm(FormRevMixin, ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = DName
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
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)
|
||||
|
||||
|
||||
class DelDNameForm(FormRevMixin, Form):
|
||||
"""Delete a set of DNAME entries"""
|
||||
|
||||
dnames = forms.ModelMultipleChoiceField(
|
||||
queryset=Txt.objects.none(),
|
||||
label=_("Current DNAME records"),
|
||||
widget=forms.CheckboxSelectMultiple
|
||||
widget=forms.CheckboxSelectMultiple,
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
instances = kwargs.pop('instances', None)
|
||||
instances = kwargs.pop("instances", None)
|
||||
super(DelDNameForm, self).__init__(*args, **kwargs)
|
||||
if instances:
|
||||
self.fields['dnames'].queryset = instances
|
||||
self.fields["dnames"].queryset = instances
|
||||
else:
|
||||
self.fields['dnames'].queryset = DName.objects.all()
|
||||
self.fields["dnames"].queryset = DName.objects.all()
|
||||
|
||||
|
||||
class SrvForm(FormRevMixin, ModelForm):
|
||||
|
@ -463,28 +480,29 @@ class SrvForm(FormRevMixin, ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = Srv
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
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)
|
||||
|
||||
|
||||
class DelSrvForm(FormRevMixin, Form):
|
||||
"""Suppression d'un ou plusieurs Srv"""
|
||||
|
||||
srv = forms.ModelMultipleChoiceField(
|
||||
queryset=Srv.objects.none(),
|
||||
label=_("Current SRV records"),
|
||||
widget=forms.CheckboxSelectMultiple
|
||||
widget=forms.CheckboxSelectMultiple,
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
instances = kwargs.pop('instances', None)
|
||||
instances = kwargs.pop("instances", None)
|
||||
super(DelSrvForm, self).__init__(*args, **kwargs)
|
||||
if instances:
|
||||
self.fields['srv'].queryset = instances
|
||||
self.fields["srv"].queryset = instances
|
||||
else:
|
||||
self.fields['srv'].queryset = Srv.objects.all()
|
||||
self.fields["srv"].queryset = Srv.objects.all()
|
||||
|
||||
|
||||
class NasForm(FormRevMixin, ModelForm):
|
||||
|
@ -493,28 +511,29 @@ class NasForm(FormRevMixin, ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = Nas
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
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)
|
||||
|
||||
|
||||
class DelNasForm(FormRevMixin, Form):
|
||||
"""Suppression d'un ou plusieurs nas"""
|
||||
|
||||
nas = forms.ModelMultipleChoiceField(
|
||||
queryset=Nas.objects.none(),
|
||||
label=_("Current NAS devices"),
|
||||
widget=forms.CheckboxSelectMultiple
|
||||
widget=forms.CheckboxSelectMultiple,
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
instances = kwargs.pop('instances', None)
|
||||
instances = kwargs.pop("instances", None)
|
||||
super(DelNasForm, self).__init__(*args, **kwargs)
|
||||
if instances:
|
||||
self.fields['nas'].queryset = instances
|
||||
self.fields["nas"].queryset = instances
|
||||
else:
|
||||
self.fields['nas'].queryset = Nas.objects.all()
|
||||
self.fields["nas"].queryset = Nas.objects.all()
|
||||
|
||||
|
||||
class RoleForm(FormRevMixin, ModelForm):
|
||||
|
@ -522,32 +541,32 @@ class RoleForm(FormRevMixin, ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = Role
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
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)
|
||||
self.fields['servers'].queryset = (Interface.objects.all()
|
||||
.select_related(
|
||||
'domain__extension'
|
||||
))
|
||||
self.fields["servers"].queryset = Interface.objects.all().select_related(
|
||||
"domain__extension"
|
||||
)
|
||||
|
||||
|
||||
class DelRoleForm(FormRevMixin, Form):
|
||||
"""Deletion of one or several roles."""
|
||||
|
||||
role = forms.ModelMultipleChoiceField(
|
||||
queryset=Role.objects.none(),
|
||||
label=_("Current roles"),
|
||||
widget=forms.CheckboxSelectMultiple
|
||||
widget=forms.CheckboxSelectMultiple,
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
instances = kwargs.pop('instances', None)
|
||||
instances = kwargs.pop("instances", None)
|
||||
super(DelRoleForm, self).__init__(*args, **kwargs)
|
||||
if instances:
|
||||
self.fields['role'].queryset = instances
|
||||
self.fields["role"].queryset = instances
|
||||
else:
|
||||
self.fields['role'].queryset = Role.objects.all()
|
||||
self.fields["role"].queryset = Role.objects.all()
|
||||
|
||||
|
||||
class ServiceForm(FormRevMixin, ModelForm):
|
||||
|
@ -555,15 +574,14 @@ class ServiceForm(FormRevMixin, ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = Service
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
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)
|
||||
self.fields['servers'].queryset = (Interface.objects.all()
|
||||
.select_related(
|
||||
'domain__extension'
|
||||
))
|
||||
self.fields["servers"].queryset = Interface.objects.all().select_related(
|
||||
"domain__extension"
|
||||
)
|
||||
|
||||
def save(self, commit=True):
|
||||
# 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)
|
||||
if commit:
|
||||
instance.save()
|
||||
instance.process_link(self.cleaned_data.get('servers'))
|
||||
instance.process_link(self.cleaned_data.get("servers"))
|
||||
return instance
|
||||
|
||||
|
||||
class DelServiceForm(FormRevMixin, Form):
|
||||
"""Suppression d'un ou plusieurs service"""
|
||||
|
||||
service = forms.ModelMultipleChoiceField(
|
||||
queryset=Service.objects.none(),
|
||||
label=_("Current services"),
|
||||
widget=forms.CheckboxSelectMultiple
|
||||
widget=forms.CheckboxSelectMultiple,
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
instances = kwargs.pop('instances', None)
|
||||
instances = kwargs.pop("instances", None)
|
||||
super(DelServiceForm, self).__init__(*args, **kwargs)
|
||||
if instances:
|
||||
self.fields['service'].queryset = instances
|
||||
self.fields["service"].queryset = instances
|
||||
else:
|
||||
self.fields['service'].queryset = Service.objects.all()
|
||||
self.fields["service"].queryset = Service.objects.all()
|
||||
|
||||
|
||||
class VlanForm(FormRevMixin, ModelForm):
|
||||
|
@ -597,39 +616,41 @@ class VlanForm(FormRevMixin, ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = Vlan
|
||||
fields = ['vlan_id', 'name', 'comment']
|
||||
fields = ["vlan_id", "name", "comment"]
|
||||
|
||||
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)
|
||||
|
||||
|
||||
class EditOptionVlanForm(FormRevMixin, ModelForm):
|
||||
"""Ajout d'un vlan : id, nom"""
|
||||
|
||||
class Meta:
|
||||
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):
|
||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
||||
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||
super(EditOptionVlanForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||
|
||||
|
||||
class DelVlanForm(FormRevMixin, Form):
|
||||
"""Suppression d'un ou plusieurs vlans"""
|
||||
|
||||
vlan = forms.ModelMultipleChoiceField(
|
||||
queryset=Vlan.objects.none(),
|
||||
label=_("Current VLANs"),
|
||||
widget=forms.CheckboxSelectMultiple
|
||||
widget=forms.CheckboxSelectMultiple,
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
instances = kwargs.pop('instances', None)
|
||||
instances = kwargs.pop("instances", None)
|
||||
super(DelVlanForm, self).__init__(*args, **kwargs)
|
||||
if instances:
|
||||
self.fields['vlan'].queryset = instances
|
||||
self.fields["vlan"].queryset = instances
|
||||
else:
|
||||
self.fields['vlan'].queryset = Vlan.objects.all()
|
||||
self.fields["vlan"].queryset = Vlan.objects.all()
|
||||
|
||||
|
||||
class EditOuverturePortConfigForm(FormRevMixin, ModelForm):
|
||||
|
@ -638,14 +659,12 @@ class EditOuverturePortConfigForm(FormRevMixin, ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = Interface
|
||||
fields = ['port_lists']
|
||||
fields = ["port_lists"]
|
||||
|
||||
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__(
|
||||
*args,
|
||||
prefix=prefix,
|
||||
**kwargs
|
||||
*args, prefix=prefix, **kwargs
|
||||
)
|
||||
|
||||
|
||||
|
@ -655,15 +674,11 @@ class EditOuverturePortListForm(FormRevMixin, ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = OuverturePortList
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
||||
super(EditOuverturePortListForm, self).__init__(
|
||||
*args,
|
||||
prefix=prefix,
|
||||
**kwargs
|
||||
)
|
||||
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||
super(EditOuverturePortListForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||
|
||||
|
||||
class SshFpForm(FormRevMixin, ModelForm):
|
||||
|
@ -671,12 +686,8 @@ class SshFpForm(FormRevMixin, ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = SshFp
|
||||
exclude = ('machine',)
|
||||
exclude = ("machine",)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
||||
super(SshFpForm, self).__init__(
|
||||
*args,
|
||||
prefix=prefix,
|
||||
**kwargs
|
||||
)
|
||||
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||
super(SshFpForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||
|
|
|
@ -29,32 +29,50 @@ import django.db.models.deletion
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('users', '0005_auto_20160702_0006'),
|
||||
]
|
||||
dependencies = [("users", "0005_auto_20160702_0006")]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Machine',
|
||||
name="Machine",
|
||||
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(
|
||||
name='MachineType',
|
||||
name="MachineType",
|
||||
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(
|
||||
model_name='machine',
|
||||
name='type',
|
||||
field=models.ForeignKey(to='machines.MachineType', on_delete=django.db.models.deletion.PROTECT),
|
||||
model_name="machine",
|
||||
name="type",
|
||||
field=models.ForeignKey(
|
||||
to="machines.MachineType", on_delete=django.db.models.deletion.PROTECT
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='machine',
|
||||
name='user',
|
||||
field=models.ForeignKey(to='users.User', on_delete=django.db.models.deletion.PROTECT),
|
||||
model_name="machine",
|
||||
name="user",
|
||||
field=models.ForeignKey(
|
||||
to="users.User", on_delete=django.db.models.deletion.PROTECT
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -30,36 +30,57 @@ import macaddress.fields
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('machines', '0001_initial'),
|
||||
]
|
||||
dependencies = [("machines", "0001_initial")]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Interface',
|
||||
name="Interface",
|
||||
fields=[
|
||||
('id', models.AutoField(serialize=False, 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)),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
serialize=False,
|
||||
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(
|
||||
name='IpList',
|
||||
name="IpList",
|
||||
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(
|
||||
model_name='interface',
|
||||
name='ipv4',
|
||||
field=models.OneToOneField(null=True, to='machines.IpList', blank=True, on_delete=django.db.models.deletion.PROTECT),
|
||||
model_name="interface",
|
||||
name="ipv4",
|
||||
field=models.OneToOneField(
|
||||
null=True,
|
||||
to="machines.IpList",
|
||||
blank=True,
|
||||
on_delete=django.db.models.deletion.PROTECT,
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='interface',
|
||||
name='machine',
|
||||
field=models.ForeignKey(to='machines.Machine', on_delete=django.db.models.deletion.PROTECT),
|
||||
model_name="interface",
|
||||
name="machine",
|
||||
field=models.ForeignKey(
|
||||
to="machines.Machine", on_delete=django.db.models.deletion.PROTECT
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -29,14 +29,12 @@ import macaddress.fields
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('machines', '0002_auto_20160703_1444'),
|
||||
]
|
||||
dependencies = [("machines", "0002_auto_20160703_1444")]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='interface',
|
||||
name='mac_address',
|
||||
model_name="interface",
|
||||
name="mac_address",
|
||||
field=macaddress.fields.MACAddressField(integer=True, unique=True),
|
||||
),
|
||||
)
|
||||
]
|
||||
|
|
|
@ -28,14 +28,12 @@ from django.db import migrations, models
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('machines', '0003_auto_20160703_1450'),
|
||||
]
|
||||
dependencies = [("machines", "0003_auto_20160703_1450")]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='iplist',
|
||||
name='ipv4',
|
||||
field=models.GenericIPAddressField(protocol='IPv4', unique=True),
|
||||
),
|
||||
model_name="iplist",
|
||||
name="ipv4",
|
||||
field=models.GenericIPAddressField(protocol="IPv4", unique=True),
|
||||
)
|
||||
]
|
||||
|
|
|
@ -28,19 +28,15 @@ from django.db import migrations, models
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('machines', '0004_auto_20160703_1451'),
|
||||
]
|
||||
dependencies = [("machines", "0004_auto_20160703_1451")]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name='interface',
|
||||
old_name='name',
|
||||
new_name='dns',
|
||||
),
|
||||
migrations.RenameField(model_name="interface", old_name="name", new_name="dns"),
|
||||
migrations.AddField(
|
||||
model_name='machine',
|
||||
name='name',
|
||||
field=models.CharField(blank=True, unique=True, max_length=255, help_text='Optionnel'),
|
||||
model_name="machine",
|
||||
name="name",
|
||||
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