mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-22 11:23:10 +00:00
Release : 2.8
This commit is contained in:
commit
56fdfca1aa
759 changed files with 27074 additions and 16710 deletions
25
CHANGELOG.md
25
CHANGELOG.md
|
@ -178,3 +178,28 @@ Be carefull, you need the proper rights to edit a DocumentTemplate.
|
||||||
Re2o now sends subscription voucher when an invoice is controlled. It uses one
|
Re2o now sends subscription voucher when an invoice is controlled. It uses one
|
||||||
of the templates. You also need to set the name of the president of your association
|
of the templates. You also need to set the name of the president of your association
|
||||||
to be set in your settings.
|
to be set in your settings.
|
||||||
|
|
||||||
|
## MR 427: Tickets
|
||||||
|
Manually edit `settings_local.py` to provide the new `OPTIONNAL_APPS` lists:
|
||||||
|
```python
|
||||||
|
OPTIONNAL_APPS_RE2O = ('tickets',)
|
||||||
|
OPTIONNAL_APPS = OPTIONNAL_APPS_RE2O + (...,...,)
|
||||||
|
```
|
||||||
|
|
||||||
|
Don't forget to run migrations afterwards.
|
||||||
|
|
||||||
|
## MR 433 : upgrade django-ldapdb to 1.3.0
|
||||||
|
|
||||||
|
Uninstall the existing django-ldapdb installation
|
||||||
|
|
||||||
|
pip3 uninstall django-ldapdb
|
||||||
|
|
||||||
|
Install debian(buster) supported version
|
||||||
|
|
||||||
|
apt install python3-django-ldapdb
|
||||||
|
|
||||||
|
If you use MySQL, please run
|
||||||
|
|
||||||
|
```
|
||||||
|
SET GLOBAL SQL_MODE=ANSI_QUOTES;
|
||||||
|
```
|
||||||
|
|
20
api/acl.py
20
api/acl.py
|
@ -33,21 +33,21 @@ from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
def _create_api_permission():
|
def _create_api_permission():
|
||||||
"""Creates the 'use_api' permission if not created.
|
"""Creates the 'use_api' permission if not created.
|
||||||
|
|
||||||
The 'use_api' is a fake permission in the sense it is not associated with an
|
The 'use_api' is a fake permission in the sense it is not associated with an
|
||||||
existing model and this ensure the permission is created every time this file
|
existing model and this ensure the permission is created every time this file
|
||||||
is imported.
|
is imported.
|
||||||
"""
|
"""
|
||||||
api_content_type, created = ContentType.objects.get_or_create(
|
api_content_type, created = ContentType.objects.get_or_create(
|
||||||
app_label=settings.API_CONTENT_TYPE_APP_LABEL,
|
app_label=settings.API_CONTENT_TYPE_APP_LABEL,
|
||||||
model=settings.API_CONTENT_TYPE_MODEL
|
model=settings.API_CONTENT_TYPE_MODEL,
|
||||||
)
|
)
|
||||||
if created:
|
if created:
|
||||||
api_content_type.save()
|
api_content_type.save()
|
||||||
api_permission, created = Permission.objects.get_or_create(
|
api_permission, created = Permission.objects.get_or_create(
|
||||||
name=settings.API_PERMISSION_NAME,
|
name=settings.API_PERMISSION_NAME,
|
||||||
content_type=api_content_type,
|
content_type=api_content_type,
|
||||||
codename=settings.API_PERMISSION_CODENAME
|
codename=settings.API_PERMISSION_CODENAME,
|
||||||
)
|
)
|
||||||
if created:
|
if created:
|
||||||
api_permission.save()
|
api_permission.save()
|
||||||
|
@ -67,9 +67,13 @@ def can_view(user):
|
||||||
viewing is granted and msg is a message (can be None).
|
viewing is granted and msg is a message (can be None).
|
||||||
"""
|
"""
|
||||||
kwargs = {
|
kwargs = {
|
||||||
'app_label': settings.API_CONTENT_TYPE_APP_LABEL,
|
"app_label": settings.API_CONTENT_TYPE_APP_LABEL,
|
||||||
'codename': settings.API_PERMISSION_CODENAME
|
"codename": settings.API_PERMISSION_CODENAME,
|
||||||
}
|
}
|
||||||
can = user.has_perm('%(app_label)s.%(codename)s' % kwargs)
|
permission = "%(app_label)s.%(codename)s" % kwargs
|
||||||
return can, None if can else _("You don't have the right to see this"
|
can = user.has_perm(permission)
|
||||||
" application.")
|
return (
|
||||||
|
can,
|
||||||
|
None if can else _("You don't have the right to view this application."),
|
||||||
|
(permission,),
|
||||||
|
)
|
||||||
|
|
|
@ -41,9 +41,7 @@ class ExpiringTokenAuthentication(TokenAuthentication):
|
||||||
user, token = base.authenticate_credentials(key)
|
user, token = base.authenticate_credentials(key)
|
||||||
|
|
||||||
# Check that the genration time of the token is not too old
|
# Check that the genration time of the token is not too old
|
||||||
token_duration = datetime.timedelta(
|
token_duration = datetime.timedelta(seconds=settings.API_TOKEN_DURATION)
|
||||||
seconds=settings.API_TOKEN_DURATION
|
|
||||||
)
|
|
||||||
utc_now = datetime.datetime.now(datetime.timezone.utc)
|
utc_now = datetime.datetime.now(datetime.timezone.utc)
|
||||||
if token.created < utc_now - token_duration:
|
if token.created < utc_now - token_duration:
|
||||||
raise exceptions.AuthenticationFailed(_("The token has expired."))
|
raise exceptions.AuthenticationFailed(_("The token has expired."))
|
||||||
|
|
|
@ -21,7 +21,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: 2.5\n"
|
"Project-Id-Version: 2.5\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2019-01-08 23:06+0100\n"
|
"POT-Creation-Date: 2019-11-19 23:43+0100\n"
|
||||||
"PO-Revision-Date: 2019-01-07 01:37+0100\n"
|
"PO-Revision-Date: 2019-01-07 01:37+0100\n"
|
||||||
"Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n"
|
"Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n"
|
||||||
"Language-Team: \n"
|
"Language-Team: \n"
|
||||||
|
@ -31,10 +31,10 @@ msgstr ""
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||||
|
|
||||||
#: acl.py:74
|
#: api/acl.py:77
|
||||||
msgid "You don't have the right to see this application."
|
msgid "You don't have the right to view this application."
|
||||||
msgstr "Vous n'avez pas le droit de voir cette application."
|
msgstr "Vous n'avez pas le droit de voir cette application."
|
||||||
|
|
||||||
#: authentication.py:49
|
#: api/authentication.py:47
|
||||||
msgid "The token has expired."
|
msgid "The token has expired."
|
||||||
msgstr "Le jeton a expiré."
|
msgstr "Le jeton a expiré."
|
||||||
|
|
|
@ -38,8 +38,9 @@ class PageSizedPagination(pagination.PageNumberPagination):
|
||||||
max_page_size: The maximum number of results a page can output no
|
max_page_size: The maximum number of results a page can output no
|
||||||
matter what is requested.
|
matter what is requested.
|
||||||
"""
|
"""
|
||||||
page_size_query_param = 'page_size'
|
|
||||||
all_pages_strings = ('all',)
|
page_size_query_param = "page_size"
|
||||||
|
all_pages_strings = ("all",)
|
||||||
max_page_size = 10000
|
max_page_size = 10000
|
||||||
|
|
||||||
def get_page_size(self, request):
|
def get_page_size(self, request):
|
||||||
|
|
|
@ -55,17 +55,21 @@ def _get_param_in_view(view, param_name):
|
||||||
AssertionError: None of the getter function or the attribute are
|
AssertionError: None of the getter function or the attribute are
|
||||||
defined in the view.
|
defined in the view.
|
||||||
"""
|
"""
|
||||||
assert hasattr(view, 'get_' + param_name) \
|
assert (
|
||||||
or getattr(view, param_name, None) is not None, (
|
hasattr(view, "get_" + param_name)
|
||||||
'cannot apply {} on a view that does not set '
|
or getattr(view, param_name, None) is not None
|
||||||
'`.{}` or have a `.get_{}()` method.'
|
), (
|
||||||
).format(self.__class__.__name__, param_name, param_name)
|
"cannot apply {} on a view that does not set "
|
||||||
|
"`.{}` or have a `.get_{}()` method."
|
||||||
|
).format(
|
||||||
|
self.__class__.__name__, param_name, param_name
|
||||||
|
)
|
||||||
|
|
||||||
if hasattr(view, 'get_' + param_name):
|
if hasattr(view, "get_" + param_name):
|
||||||
param = getattr(view, 'get_' + param_name)()
|
param = getattr(view, "get_" + param_name)()
|
||||||
assert param is not None, (
|
assert param is not None, ("{}.get_{}() returned None").format(
|
||||||
'{}.get_{}() returned None'
|
view.__class__.__name__, param_name
|
||||||
).format(view.__class__.__name__, param_name)
|
)
|
||||||
return param
|
return param
|
||||||
return getattr(view, param_name)
|
return getattr(view, param_name)
|
||||||
|
|
||||||
|
@ -97,7 +101,7 @@ class ACLPermission(permissions.BasePermission):
|
||||||
rest_framework.exception.MethodNotAllowed: The requested method
|
rest_framework.exception.MethodNotAllowed: The requested method
|
||||||
is not allowed for this view.
|
is not allowed for this view.
|
||||||
"""
|
"""
|
||||||
perms_map = _get_param_in_view(view, 'perms_map')
|
perms_map = _get_param_in_view(view, "perms_map")
|
||||||
|
|
||||||
if method not in perms_map:
|
if method not in perms_map:
|
||||||
raise exceptions.MethodNotAllowed(method)
|
raise exceptions.MethodNotAllowed(method)
|
||||||
|
@ -123,7 +127,7 @@ class ACLPermission(permissions.BasePermission):
|
||||||
"""
|
"""
|
||||||
# Workaround to ensure ACLPermissions are not applied
|
# Workaround to ensure ACLPermissions are not applied
|
||||||
# to the root view when using DefaultRouter.
|
# to the root view when using DefaultRouter.
|
||||||
if getattr(view, '_ignore_model_permissions', False):
|
if getattr(view, "_ignore_model_permissions", False):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if not request.user or not request.user.is_authenticated:
|
if not request.user or not request.user.is_authenticated:
|
||||||
|
@ -148,22 +152,22 @@ class AutodetectACLPermission(permissions.BasePermission):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
perms_map = {
|
perms_map = {
|
||||||
'GET': [can_see_api, lambda model: model.can_view_all],
|
"GET": [can_see_api, lambda model: model.can_view_all],
|
||||||
'OPTIONS': [can_see_api, lambda model: model.can_view_all],
|
"OPTIONS": [can_see_api, lambda model: model.can_view_all],
|
||||||
'HEAD': [can_see_api, lambda model: model.can_view_all],
|
"HEAD": [can_see_api, lambda model: model.can_view_all],
|
||||||
'POST': [can_see_api, lambda model: model.can_create],
|
"POST": [can_see_api, lambda model: model.can_create],
|
||||||
'PUT': [], # No restrictions, apply to objects
|
"PUT": [], # No restrictions, apply to objects
|
||||||
'PATCH': [], # No restrictions, apply to objects
|
"PATCH": [], # No restrictions, apply to objects
|
||||||
'DELETE': [], # No restrictions, apply to objects
|
"DELETE": [], # No restrictions, apply to objects
|
||||||
}
|
}
|
||||||
perms_obj_map = {
|
perms_obj_map = {
|
||||||
'GET': [can_see_api, lambda obj: obj.can_view],
|
"GET": [can_see_api, lambda obj: obj.can_view],
|
||||||
'OPTIONS': [can_see_api, lambda obj: obj.can_view],
|
"OPTIONS": [can_see_api, lambda obj: obj.can_view],
|
||||||
'HEAD': [can_see_api, lambda obj: obj.can_view],
|
"HEAD": [can_see_api, lambda obj: obj.can_view],
|
||||||
'POST': [], # No restrictions, apply to models
|
"POST": [], # No restrictions, apply to models
|
||||||
'PUT': [can_see_api, lambda obj: obj.can_edit],
|
"PUT": [can_see_api, lambda obj: obj.can_edit],
|
||||||
'PATCH': [can_see_api, lambda obj: obj.can_edit],
|
"PATCH": [can_see_api, lambda obj: obj.can_edit],
|
||||||
'DELETE': [can_see_api, lambda obj: obj.can_delete],
|
"DELETE": [can_see_api, lambda obj: obj.can_delete],
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_required_permissions(self, method, model):
|
def get_required_permissions(self, method, model):
|
||||||
|
@ -210,7 +214,7 @@ class AutodetectACLPermission(permissions.BasePermission):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _queryset(view):
|
def _queryset(view):
|
||||||
return _get_param_in_view(view, 'queryset')
|
return _get_param_in_view(view, "queryset")
|
||||||
|
|
||||||
def has_permission(self, request, view):
|
def has_permission(self, request, view):
|
||||||
"""Check that the user has the model-based permissions to perform
|
"""Check that the user has the model-based permissions to perform
|
||||||
|
@ -232,7 +236,7 @@ class AutodetectACLPermission(permissions.BasePermission):
|
||||||
"""
|
"""
|
||||||
# Workaround to ensure ACLPermissions are not applied
|
# Workaround to ensure ACLPermissions are not applied
|
||||||
# to the root view when using DefaultRouter.
|
# to the root view when using DefaultRouter.
|
||||||
if getattr(view, '_ignore_model_permissions', False):
|
if getattr(view, "_ignore_model_permissions", False):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if not request.user or not request.user.is_authenticated:
|
if not request.user or not request.user.is_authenticated:
|
||||||
|
@ -274,7 +278,7 @@ class AutodetectACLPermission(permissions.BasePermission):
|
||||||
# to make another lookup.
|
# to make another lookup.
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
read_perms = self.get_required_object_permissions('GET', obj)
|
read_perms = self.get_required_object_permissions("GET", obj)
|
||||||
if not read_perms(request.user)[0]:
|
if not read_perms(request.user)[0]:
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
|
|
|
@ -74,9 +74,9 @@ class AllViewsRouter(DefaultRouter):
|
||||||
Returns:
|
Returns:
|
||||||
The name to use for this route.
|
The name to use for this route.
|
||||||
"""
|
"""
|
||||||
return pattern.split('/')[-1]
|
return pattern.split("/")[-1]
|
||||||
|
|
||||||
def get_api_root_view(self, schema_urls=None):
|
def get_api_root_view(self, schema_urls=None, api_urls=None):
|
||||||
"""Create a class-based view to use as the API root.
|
"""Create a class-based view to use as the API root.
|
||||||
|
|
||||||
Highly inspired by the base class. See details on the implementation
|
Highly inspired by the base class. See details on the implementation
|
||||||
|
@ -102,12 +102,10 @@ class AllViewsRouter(DefaultRouter):
|
||||||
if schema_urls and self.schema_title:
|
if schema_urls and self.schema_title:
|
||||||
view_renderers += list(self.schema_renderers)
|
view_renderers += list(self.schema_renderers)
|
||||||
schema_generator = SchemaGenerator(
|
schema_generator = SchemaGenerator(
|
||||||
title=self.schema_title,
|
title=self.schema_title, patterns=schema_urls
|
||||||
patterns=schema_urls
|
|
||||||
)
|
)
|
||||||
schema_media_types = [
|
schema_media_types = [
|
||||||
renderer.media_type
|
renderer.media_type for renderer in self.schema_renderers
|
||||||
for renderer in self.schema_renderers
|
|
||||||
]
|
]
|
||||||
|
|
||||||
class APIRoot(views.APIView):
|
class APIRoot(views.APIView):
|
||||||
|
@ -128,14 +126,14 @@ class AllViewsRouter(DefaultRouter):
|
||||||
namespace = request.resolver_match.namespace
|
namespace = request.resolver_match.namespace
|
||||||
for key, url_name in api_root_dict.items():
|
for key, url_name in api_root_dict.items():
|
||||||
if namespace:
|
if namespace:
|
||||||
url_name = namespace + ':' + url_name
|
url_name = namespace + ":" + url_name
|
||||||
try:
|
try:
|
||||||
ret[key] = reverse(
|
ret[key] = reverse(
|
||||||
url_name,
|
url_name,
|
||||||
args=args,
|
args=args,
|
||||||
kwargs=kwargs,
|
kwargs=kwargs,
|
||||||
request=request,
|
request=request,
|
||||||
format=kwargs.get('format', None)
|
format=kwargs.get("format", None),
|
||||||
)
|
)
|
||||||
except NoReverseMatch:
|
except NoReverseMatch:
|
||||||
# Don't bail out if eg. no list routes exist, only detail routes.
|
# Don't bail out if eg. no list routes exist, only detail routes.
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -24,28 +24,24 @@
|
||||||
|
|
||||||
# RestFramework config for API
|
# RestFramework config for API
|
||||||
REST_FRAMEWORK = {
|
REST_FRAMEWORK = {
|
||||||
'URL_FIELD_NAME': 'api_url',
|
"URL_FIELD_NAME": "api_url",
|
||||||
'DEFAULT_AUTHENTICATION_CLASSES': (
|
"DEFAULT_AUTHENTICATION_CLASSES": (
|
||||||
'api.authentication.ExpiringTokenAuthentication',
|
"api.authentication.ExpiringTokenAuthentication",
|
||||||
'rest_framework.authentication.SessionAuthentication',
|
"rest_framework.authentication.SessionAuthentication",
|
||||||
),
|
),
|
||||||
'DEFAULT_PERMISSION_CLASSES': (
|
"DEFAULT_PERMISSION_CLASSES": ("api.permissions.AutodetectACLPermission",),
|
||||||
'api.permissions.AutodetectACLPermission',
|
"DEFAULT_PAGINATION_CLASS": "api.pagination.PageSizedPagination",
|
||||||
),
|
"PAGE_SIZE": 100,
|
||||||
'DEFAULT_PAGINATION_CLASS': 'api.pagination.PageSizedPagination',
|
|
||||||
'PAGE_SIZE': 100
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# API permission settings
|
# API permission settings
|
||||||
API_CONTENT_TYPE_APP_LABEL = 'api'
|
API_CONTENT_TYPE_APP_LABEL = "api"
|
||||||
API_CONTENT_TYPE_MODEL = 'api'
|
API_CONTENT_TYPE_MODEL = "api"
|
||||||
API_PERMISSION_NAME = 'Can use the API'
|
API_PERMISSION_NAME = "Can use the API"
|
||||||
API_PERMISSION_CODENAME = 'use_api'
|
API_PERMISSION_CODENAME = "use_api"
|
||||||
|
|
||||||
# Activate token authentication
|
# Activate token authentication
|
||||||
API_APPS = (
|
API_APPS = ("rest_framework.authtoken",)
|
||||||
'rest_framework.authtoken',
|
|
||||||
)
|
|
||||||
|
|
||||||
# The expiration time for an authentication token
|
# The expiration time for an authentication token
|
||||||
API_TOKEN_DURATION = 86400 # 24 hours
|
API_TOKEN_DURATION = 86400 # 24 hours
|
||||||
|
|
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
|
superuser: A superuser (with all permissions) used for the tests and
|
||||||
initialized at the beggining of this test case.
|
initialized at the beggining of this test case.
|
||||||
"""
|
"""
|
||||||
no_auth_endpoints = [
|
|
||||||
'/api/'
|
no_auth_endpoints = ["/api/"]
|
||||||
]
|
|
||||||
auth_no_perm_endpoints = []
|
auth_no_perm_endpoints = []
|
||||||
auth_perm_endpoints = [
|
auth_perm_endpoints = [
|
||||||
'/api/cotisations/article/',
|
"/api/cotisations/article/",
|
||||||
'/api/cotisations/article/1/',
|
"/api/cotisations/article/1/",
|
||||||
'/api/cotisations/banque/',
|
"/api/cotisations/banque/",
|
||||||
'/api/cotisations/banque/1/',
|
"/api/cotisations/banque/1/",
|
||||||
'/api/cotisations/cotisation/',
|
"/api/cotisations/cotisation/",
|
||||||
'/api/cotisations/cotisation/1/',
|
"/api/cotisations/cotisation/1/",
|
||||||
'/api/cotisations/facture/',
|
"/api/cotisations/facture/",
|
||||||
'/api/cotisations/facture/1/',
|
"/api/cotisations/facture/1/",
|
||||||
'/api/cotisations/paiement/',
|
"/api/cotisations/paiement/",
|
||||||
'/api/cotisations/paiement/1/',
|
"/api/cotisations/paiement/1/",
|
||||||
'/api/cotisations/vente/',
|
"/api/cotisations/vente/",
|
||||||
'/api/cotisations/vente/1/',
|
"/api/cotisations/vente/1/",
|
||||||
'/api/machines/domain/',
|
"/api/machines/domain/",
|
||||||
'/api/machines/domain/1/',
|
"/api/machines/domain/1/",
|
||||||
'/api/machines/extension/',
|
"/api/machines/extension/",
|
||||||
'/api/machines/extension/1/',
|
"/api/machines/extension/1/",
|
||||||
'/api/machines/interface/',
|
"/api/machines/interface/",
|
||||||
'/api/machines/interface/1/',
|
"/api/machines/interface/1/",
|
||||||
'/api/machines/iplist/',
|
"/api/machines/iplist/",
|
||||||
'/api/machines/iplist/1/',
|
"/api/machines/iplist/1/",
|
||||||
'/api/machines/iptype/',
|
"/api/machines/iptype/",
|
||||||
'/api/machines/iptype/1/',
|
"/api/machines/iptype/1/",
|
||||||
'/api/machines/ipv6list/',
|
"/api/machines/ipv6list/",
|
||||||
'/api/machines/ipv6list/1/',
|
"/api/machines/ipv6list/1/",
|
||||||
'/api/machines/machine/',
|
"/api/machines/machine/",
|
||||||
'/api/machines/machine/1/',
|
"/api/machines/machine/1/",
|
||||||
'/api/machines/machinetype/',
|
"/api/machines/machinetype/",
|
||||||
'/api/machines/machinetype/1/',
|
"/api/machines/machinetype/1/",
|
||||||
'/api/machines/mx/',
|
"/api/machines/mx/",
|
||||||
'/api/machines/mx/1/',
|
"/api/machines/mx/1/",
|
||||||
'/api/machines/nas/',
|
"/api/machines/nas/",
|
||||||
'/api/machines/nas/1/',
|
"/api/machines/nas/1/",
|
||||||
'/api/machines/ns/',
|
"/api/machines/ns/",
|
||||||
'/api/machines/ns/1/',
|
"/api/machines/ns/1/",
|
||||||
'/api/machines/ouvertureportlist/',
|
"/api/machines/ouvertureportlist/",
|
||||||
'/api/machines/ouvertureportlist/1/',
|
"/api/machines/ouvertureportlist/1/",
|
||||||
'/api/machines/ouvertureport/',
|
"/api/machines/ouvertureport/",
|
||||||
'/api/machines/ouvertureport/1/',
|
"/api/machines/ouvertureport/1/",
|
||||||
'/api/machines/servicelink/',
|
"/api/machines/servicelink/",
|
||||||
'/api/machines/servicelink/1/',
|
"/api/machines/servicelink/1/",
|
||||||
'/api/machines/service/',
|
"/api/machines/service/",
|
||||||
'/api/machines/service/1/',
|
"/api/machines/service/1/",
|
||||||
'/api/machines/soa/',
|
"/api/machines/soa/",
|
||||||
'/api/machines/soa/1/',
|
"/api/machines/soa/1/",
|
||||||
'/api/machines/srv/',
|
"/api/machines/srv/",
|
||||||
'/api/machines/srv/1/',
|
"/api/machines/srv/1/",
|
||||||
'/api/machines/txt/',
|
"/api/machines/txt/",
|
||||||
'/api/machines/txt/1/',
|
"/api/machines/txt/1/",
|
||||||
'/api/machines/vlan/',
|
"/api/machines/vlan/",
|
||||||
'/api/machines/vlan/1/',
|
"/api/machines/vlan/1/",
|
||||||
'/api/preferences/optionaluser/',
|
"/api/preferences/optionaluser/",
|
||||||
'/api/preferences/optionalmachine/',
|
"/api/preferences/optionalmachine/",
|
||||||
'/api/preferences/optionaltopologie/',
|
"/api/preferences/optionaltopologie/",
|
||||||
'/api/preferences/generaloption/',
|
"/api/preferences/generaloption/",
|
||||||
'/api/preferences/service/',
|
"/api/preferences/service/",
|
||||||
'/api/preferences/service/1/',
|
"/api/preferences/service/1/",
|
||||||
'/api/preferences/assooption/',
|
"/api/preferences/assooption/",
|
||||||
'/api/preferences/homeoption/',
|
"/api/preferences/homeoption/",
|
||||||
'/api/preferences/mailmessageoption/',
|
"/api/preferences/mailmessageoption/",
|
||||||
'/api/topologie/acesspoint/',
|
"/api/topologie/acesspoint/",
|
||||||
# 2nd machine to be create (machines_machine_1, topologie_accesspoint_1)
|
# 2nd machine to be create (machines_machine_1, topologie_accesspoint_1)
|
||||||
'/api/topologie/acesspoint/2/',
|
"/api/topologie/acesspoint/2/",
|
||||||
'/api/topologie/building/',
|
"/api/topologie/building/",
|
||||||
'/api/topologie/building/1/',
|
"/api/topologie/building/1/",
|
||||||
'/api/topologie/constructorswitch/',
|
"/api/topologie/constructorswitch/",
|
||||||
'/api/topologie/constructorswitch/1/',
|
"/api/topologie/constructorswitch/1/",
|
||||||
'/api/topologie/modelswitch/',
|
"/api/topologie/modelswitch/",
|
||||||
'/api/topologie/modelswitch/1/',
|
"/api/topologie/modelswitch/1/",
|
||||||
'/api/topologie/room/',
|
"/api/topologie/room/",
|
||||||
'/api/topologie/room/1/',
|
"/api/topologie/room/1/",
|
||||||
'/api/topologie/server/',
|
"/api/topologie/server/",
|
||||||
# 3rd machine to be create (machines_machine_1, topologie_accesspoint_1,
|
# 3rd machine to be create (machines_machine_1, topologie_accesspoint_1,
|
||||||
# topologie_server_1)
|
# topologie_server_1)
|
||||||
'/api/topologie/server/3/',
|
"/api/topologie/server/3/",
|
||||||
'/api/topologie/stack/',
|
"/api/topologie/stack/",
|
||||||
'/api/topologie/stack/1/',
|
"/api/topologie/stack/1/",
|
||||||
'/api/topologie/switch/',
|
"/api/topologie/switch/",
|
||||||
# 4th machine to be create (machines_machine_1, topologie_accesspoint_1,
|
# 4th machine to be create (machines_machine_1, topologie_accesspoint_1,
|
||||||
# topologie_server_1, topologie_switch_1)
|
# topologie_server_1, topologie_switch_1)
|
||||||
'/api/topologie/switch/4/',
|
"/api/topologie/switch/4/",
|
||||||
'/api/topologie/switchbay/',
|
"/api/topologie/switchbay/",
|
||||||
'/api/topologie/switchbay/1/',
|
"/api/topologie/switchbay/1/",
|
||||||
'/api/topologie/switchport/',
|
"/api/topologie/switchport/",
|
||||||
'/api/topologie/switchport/1/',
|
"/api/topologie/switchport/1/",
|
||||||
'/api/topologie/switchport/2/',
|
"/api/topologie/switchport/2/",
|
||||||
'/api/topologie/switchport/3/',
|
"/api/topologie/switchport/3/",
|
||||||
'/api/users/adherent/',
|
"/api/users/adherent/",
|
||||||
# 3rd user to be create (stduser, superuser, users_adherent_1)
|
# 3rd user to be create (stduser, superuser, users_adherent_1)
|
||||||
'/api/users/adherent/3/',
|
"/api/users/adherent/3/",
|
||||||
'/api/users/ban/',
|
"/api/users/ban/",
|
||||||
'/api/users/ban/1/',
|
"/api/users/ban/1/",
|
||||||
'/api/users/club/',
|
"/api/users/club/",
|
||||||
# 4th user to be create (stduser, superuser, users_adherent_1,
|
# 4th user to be create (stduser, superuser, users_adherent_1,
|
||||||
# users_club_1)
|
# users_club_1)
|
||||||
'/api/users/club/4/',
|
"/api/users/club/4/",
|
||||||
'/api/users/listright/',
|
"/api/users/listright/",
|
||||||
# TODO: Merge !145
|
# TODO: Merge !145
|
||||||
# '/api/users/listright/1/',
|
# '/api/users/listright/1/',
|
||||||
'/api/users/school/',
|
"/api/users/school/",
|
||||||
'/api/users/school/1/',
|
"/api/users/school/1/",
|
||||||
'/api/users/serviceuser/',
|
"/api/users/serviceuser/",
|
||||||
'/api/users/serviceuser/1/',
|
"/api/users/serviceuser/1/",
|
||||||
'/api/users/shell/',
|
"/api/users/shell/",
|
||||||
'/api/users/shell/1/',
|
"/api/users/shell/1/",
|
||||||
'/api/users/user/',
|
"/api/users/user/",
|
||||||
'/api/users/user/1/',
|
"/api/users/user/1/",
|
||||||
'/api/users/whitelist/',
|
"/api/users/whitelist/",
|
||||||
'/api/users/whitelist/1/',
|
"/api/users/whitelist/1/",
|
||||||
'/api/dns/zones/',
|
"/api/dns/zones/",
|
||||||
'/api/dhcp/hostmacip/',
|
"/api/dhcp/hostmacip/",
|
||||||
'/api/mailing/standard',
|
"/api/mailing/standard",
|
||||||
'/api/mailing/club',
|
"/api/mailing/club",
|
||||||
'/api/services/regen/',
|
"/api/services/regen/",
|
||||||
]
|
]
|
||||||
not_found_endpoints = [
|
not_found_endpoints = [
|
||||||
'/api/cotisations/article/4242/',
|
"/api/cotisations/article/4242/",
|
||||||
'/api/cotisations/banque/4242/',
|
"/api/cotisations/banque/4242/",
|
||||||
'/api/cotisations/cotisation/4242/',
|
"/api/cotisations/cotisation/4242/",
|
||||||
'/api/cotisations/facture/4242/',
|
"/api/cotisations/facture/4242/",
|
||||||
'/api/cotisations/paiement/4242/',
|
"/api/cotisations/paiement/4242/",
|
||||||
'/api/cotisations/vente/4242/',
|
"/api/cotisations/vente/4242/",
|
||||||
'/api/machines/domain/4242/',
|
"/api/machines/domain/4242/",
|
||||||
'/api/machines/extension/4242/',
|
"/api/machines/extension/4242/",
|
||||||
'/api/machines/interface/4242/',
|
"/api/machines/interface/4242/",
|
||||||
'/api/machines/iplist/4242/',
|
"/api/machines/iplist/4242/",
|
||||||
'/api/machines/iptype/4242/',
|
"/api/machines/iptype/4242/",
|
||||||
'/api/machines/ipv6list/4242/',
|
"/api/machines/ipv6list/4242/",
|
||||||
'/api/machines/machine/4242/',
|
"/api/machines/machine/4242/",
|
||||||
'/api/machines/machinetype/4242/',
|
"/api/machines/machinetype/4242/",
|
||||||
'/api/machines/mx/4242/',
|
"/api/machines/mx/4242/",
|
||||||
'/api/machines/nas/4242/',
|
"/api/machines/nas/4242/",
|
||||||
'/api/machines/ns/4242/',
|
"/api/machines/ns/4242/",
|
||||||
'/api/machines/ouvertureportlist/4242/',
|
"/api/machines/ouvertureportlist/4242/",
|
||||||
'/api/machines/ouvertureport/4242/',
|
"/api/machines/ouvertureport/4242/",
|
||||||
'/api/machines/servicelink/4242/',
|
"/api/machines/servicelink/4242/",
|
||||||
'/api/machines/service/4242/',
|
"/api/machines/service/4242/",
|
||||||
'/api/machines/soa/4242/',
|
"/api/machines/soa/4242/",
|
||||||
'/api/machines/srv/4242/',
|
"/api/machines/srv/4242/",
|
||||||
'/api/machines/txt/4242/',
|
"/api/machines/txt/4242/",
|
||||||
'/api/machines/vlan/4242/',
|
"/api/machines/vlan/4242/",
|
||||||
'/api/preferences/service/4242/',
|
"/api/preferences/service/4242/",
|
||||||
'/api/topologie/acesspoint/4242/',
|
"/api/topologie/acesspoint/4242/",
|
||||||
'/api/topologie/building/4242/',
|
"/api/topologie/building/4242/",
|
||||||
'/api/topologie/constructorswitch/4242/',
|
"/api/topologie/constructorswitch/4242/",
|
||||||
'/api/topologie/modelswitch/4242/',
|
"/api/topologie/modelswitch/4242/",
|
||||||
'/api/topologie/room/4242/',
|
"/api/topologie/room/4242/",
|
||||||
'/api/topologie/server/4242/',
|
"/api/topologie/server/4242/",
|
||||||
'/api/topologie/stack/4242/',
|
"/api/topologie/stack/4242/",
|
||||||
'/api/topologie/switch/4242/',
|
"/api/topologie/switch/4242/",
|
||||||
'/api/topologie/switchbay/4242/',
|
"/api/topologie/switchbay/4242/",
|
||||||
'/api/topologie/switchport/4242/',
|
"/api/topologie/switchport/4242/",
|
||||||
'/api/users/adherent/4242/',
|
"/api/users/adherent/4242/",
|
||||||
'/api/users/ban/4242/',
|
"/api/users/ban/4242/",
|
||||||
'/api/users/club/4242/',
|
"/api/users/club/4242/",
|
||||||
'/api/users/listright/4242/',
|
"/api/users/listright/4242/",
|
||||||
'/api/users/school/4242/',
|
"/api/users/school/4242/",
|
||||||
'/api/users/serviceuser/4242/',
|
"/api/users/serviceuser/4242/",
|
||||||
'/api/users/shell/4242/',
|
"/api/users/shell/4242/",
|
||||||
'/api/users/user/4242/',
|
"/api/users/user/4242/",
|
||||||
'/api/users/whitelist/4242/',
|
"/api/users/whitelist/4242/",
|
||||||
]
|
]
|
||||||
|
|
||||||
stduser = None
|
stduser = None
|
||||||
|
@ -232,26 +231,18 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
|
|
||||||
# A user with no rights
|
# A user with no rights
|
||||||
cls.stduser = users.User.objects.create_user(
|
cls.stduser = users.User.objects.create_user(
|
||||||
"apistduser",
|
"apistduser", "apistduser", "apistduser@example.net", "apistduser"
|
||||||
"apistduser",
|
|
||||||
"apistduser@example.net",
|
|
||||||
"apistduser"
|
|
||||||
)
|
)
|
||||||
# A user with all the rights
|
# A user with all the rights
|
||||||
cls.superuser = users.User.objects.create_superuser(
|
cls.superuser = users.User.objects.create_superuser(
|
||||||
"apisuperuser",
|
"apisuperuser", "apisuperuser", "apisuperuser@example.net", "apisuperuser"
|
||||||
"apisuperuser",
|
|
||||||
"apisuperuser@example.net",
|
|
||||||
"apisuperuser"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Creates 1 instance for each object so the "details" endpoints
|
# Creates 1 instance for each object so the "details" endpoints
|
||||||
# can be tested too. Objects need to be created in the right order.
|
# can be tested too. Objects need to be created in the right order.
|
||||||
# Dependencies (relatedFields, ...) are highlighted by a comment at
|
# Dependencies (relatedFields, ...) are highlighted by a comment at
|
||||||
# the end of the concerned line (# Dep <model>).
|
# the end of the concerned line (# Dep <model>).
|
||||||
cls.users_school_1 = users.School.objects.create(
|
cls.users_school_1 = users.School.objects.create(name="users_school_1")
|
||||||
name="users_school_1"
|
|
||||||
)
|
|
||||||
cls.users_school_1.save()
|
cls.users_school_1.save()
|
||||||
cls.users_listshell_1 = users.ListShell.objects.create(
|
cls.users_listshell_1 = users.ListShell.objects.create(
|
||||||
shell="users_listshell_1"
|
shell="users_listshell_1"
|
||||||
|
@ -270,7 +261,7 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
registered=datetime.datetime.now(datetime.timezone.utc),
|
registered=datetime.datetime.now(datetime.timezone.utc),
|
||||||
telephone="0123456789",
|
telephone="0123456789",
|
||||||
uid_number=21102,
|
uid_number=21102,
|
||||||
rezo_rez_uid=21102
|
rezo_rez_uid=21102,
|
||||||
)
|
)
|
||||||
cls.users_user_1 = cls.users_adherent_1
|
cls.users_user_1 = cls.users_adherent_1
|
||||||
cls.cotisations_article_1 = cotisations.Article.objects.create(
|
cls.cotisations_article_1 = cotisations.Article.objects.create(
|
||||||
|
@ -278,14 +269,14 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
prix=10,
|
prix=10,
|
||||||
duration=1,
|
duration=1,
|
||||||
type_user=cotisations.Article.USER_TYPES[0][0],
|
type_user=cotisations.Article.USER_TYPES[0][0],
|
||||||
type_cotisation=cotisations.Article.COTISATION_TYPE[0][0]
|
type_cotisation=cotisations.Article.COTISATION_TYPE[0][0],
|
||||||
)
|
)
|
||||||
cls.cotisations_banque_1 = cotisations.Banque.objects.create(
|
cls.cotisations_banque_1 = cotisations.Banque.objects.create(
|
||||||
name="cotisations_banque_1"
|
name="cotisations_banque_1"
|
||||||
)
|
)
|
||||||
cls.cotisations_paiement_1 = cotisations.Paiement.objects.create(
|
cls.cotisations_paiement_1 = cotisations.Paiement.objects.create(
|
||||||
moyen="cotisations_paiement_1",
|
moyen="cotisations_paiement_1",
|
||||||
type_paiement=cotisations.Paiement.PAYMENT_TYPES[0][0]
|
type_paiement=cotisations.Paiement.PAYMENT_TYPES[0][0],
|
||||||
)
|
)
|
||||||
cls.cotisations_facture_1 = cotisations.Facture.objects.create(
|
cls.cotisations_facture_1 = cotisations.Facture.objects.create(
|
||||||
user=cls.users_user_1, # Dep users.User
|
user=cls.users_user_1, # Dep users.User
|
||||||
|
@ -294,7 +285,7 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
cheque="1234567890",
|
cheque="1234567890",
|
||||||
date=datetime.datetime.now(datetime.timezone.utc),
|
date=datetime.datetime.now(datetime.timezone.utc),
|
||||||
valid=True,
|
valid=True,
|
||||||
control=False
|
control=False,
|
||||||
)
|
)
|
||||||
cls.cotisations_vente_1 = cotisations.Vente.objects.create(
|
cls.cotisations_vente_1 = cotisations.Vente.objects.create(
|
||||||
facture=cls.cotisations_facture_1, # Dep cotisations.Facture
|
facture=cls.cotisations_facture_1, # Dep cotisations.Facture
|
||||||
|
@ -302,18 +293,18 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
name="cotisations_vente_1",
|
name="cotisations_vente_1",
|
||||||
prix=10,
|
prix=10,
|
||||||
duration=1,
|
duration=1,
|
||||||
type_cotisation=cotisations.Vente.COTISATION_TYPE[0][0]
|
type_cotisation=cotisations.Vente.COTISATION_TYPE[0][0],
|
||||||
)
|
)
|
||||||
# A cotisation is automatically created by the Vente object and
|
# A cotisation is automatically created by the Vente object and
|
||||||
# trying to create another cotisation associated with this vente
|
# trying to create another cotisation associated with this vente
|
||||||
# will fail so we simply retrieve it so it can be used in the tests
|
# will fail so we simply retrieve it so it can be used in the tests
|
||||||
cls.cotisations_cotisation_1 = cotisations.Cotisation.objects.get(
|
cls.cotisations_cotisation_1 = cotisations.Cotisation.objects.get(
|
||||||
vente=cls.cotisations_vente_1, # Dep cotisations.Vente
|
vente=cls.cotisations_vente_1 # Dep cotisations.Vente
|
||||||
)
|
)
|
||||||
cls.machines_machine_1 = machines.Machine.objects.create(
|
cls.machines_machine_1 = machines.Machine.objects.create(
|
||||||
user=cls.users_user_1, # Dep users.User
|
user=cls.users_user_1, # Dep users.User
|
||||||
name="machines_machine_1",
|
name="machines_machine_1",
|
||||||
active=True
|
active=True,
|
||||||
)
|
)
|
||||||
cls.machines_ouvertureportlist_1 = machines.OuverturePortList.objects.create(
|
cls.machines_ouvertureportlist_1 = machines.OuverturePortList.objects.create(
|
||||||
name="machines_ouvertureportlist_1"
|
name="machines_ouvertureportlist_1"
|
||||||
|
@ -324,19 +315,17 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
refresh=86400,
|
refresh=86400,
|
||||||
retry=7200,
|
retry=7200,
|
||||||
expire=3600000,
|
expire=3600000,
|
||||||
ttl=172800
|
ttl=172800,
|
||||||
)
|
)
|
||||||
cls.machines_extension_1 = machines.Extension.objects.create(
|
cls.machines_extension_1 = machines.Extension.objects.create(
|
||||||
name="machines_extension_1",
|
name="machines_extension_1",
|
||||||
need_infra=False,
|
need_infra=False,
|
||||||
# Do not set origin because of circular dependency
|
# Do not set origin because of circular dependency
|
||||||
origin_v6="2001:db8:1234::",
|
origin_v6="2001:db8:1234::",
|
||||||
soa=cls.machines_soa_1 # Dep machines.SOA
|
soa=cls.machines_soa_1, # Dep machines.SOA
|
||||||
)
|
)
|
||||||
cls.machines_vlan_1 = machines.Vlan.objects.create(
|
cls.machines_vlan_1 = machines.Vlan.objects.create(
|
||||||
vlan_id=0,
|
vlan_id=0, name="machines_vlan_1", comment="machines Vlan 1"
|
||||||
name="machines_vlan_1",
|
|
||||||
comment="machines Vlan 1"
|
|
||||||
)
|
)
|
||||||
cls.machines_iptype_1 = machines.IpType.objects.create(
|
cls.machines_iptype_1 = machines.IpType.objects.create(
|
||||||
type="machines_iptype_1",
|
type="machines_iptype_1",
|
||||||
|
@ -346,13 +335,12 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
domaine_ip_stop="10.0.0.255",
|
domaine_ip_stop="10.0.0.255",
|
||||||
prefix_v6="2001:db8:1234::",
|
prefix_v6="2001:db8:1234::",
|
||||||
vlan=cls.machines_vlan_1, # Dep machines.Vlan
|
vlan=cls.machines_vlan_1, # Dep machines.Vlan
|
||||||
ouverture_ports=cls.machines_ouvertureportlist_1 # Dep machines.OuverturePortList
|
ouverture_ports=cls.machines_ouvertureportlist_1, # Dep machines.OuverturePortList
|
||||||
)
|
)
|
||||||
# All IPs in the IpType range are autocreated so we can't create
|
# All IPs in the IpType range are autocreated so we can't create
|
||||||
# new ones and thus we only retrieve it if needed in the tests
|
# new ones and thus we only retrieve it if needed in the tests
|
||||||
cls.machines_iplist_1 = machines.IpList.objects.get(
|
cls.machines_iplist_1 = machines.IpList.objects.get(
|
||||||
ipv4="10.0.0.1",
|
ipv4="10.0.0.1", ip_type=cls.machines_iptype_1 # Dep machines.IpType
|
||||||
ip_type=cls.machines_iptype_1, # Dep machines.IpType
|
|
||||||
)
|
)
|
||||||
cls.machines_machinetype_1 = machines.MachineType.objects.create(
|
cls.machines_machinetype_1 = machines.MachineType.objects.create(
|
||||||
type="machines_machinetype_1",
|
type="machines_machinetype_1",
|
||||||
|
@ -375,16 +363,16 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
cls.machines_mx_1 = machines.Mx.objects.create(
|
cls.machines_mx_1 = machines.Mx.objects.create(
|
||||||
zone=cls.machines_extension_1, # Dep machines.Extension
|
zone=cls.machines_extension_1, # Dep machines.Extension
|
||||||
priority=10,
|
priority=10,
|
||||||
name=cls.machines_domain_1 # Dep machines.Domain
|
name=cls.machines_domain_1, # Dep machines.Domain
|
||||||
)
|
)
|
||||||
cls.machines_ns_1 = machines.Ns.objects.create(
|
cls.machines_ns_1 = machines.Ns.objects.create(
|
||||||
zone=cls.machines_extension_1, # Dep machines.Extension
|
zone=cls.machines_extension_1, # Dep machines.Extension
|
||||||
ns=cls.machines_domain_1 # Dep machines.Domain
|
ns=cls.machines_domain_1, # Dep machines.Domain
|
||||||
)
|
)
|
||||||
cls.machines_txt_1 = machines.Txt.objects.create(
|
cls.machines_txt_1 = machines.Txt.objects.create(
|
||||||
zone=cls.machines_extension_1, # Dep machines.Extension
|
zone=cls.machines_extension_1, # Dep machines.Extension
|
||||||
field1="machines_txt_1",
|
field1="machines_txt_1",
|
||||||
field2="machies Txt 1"
|
field2="machies Txt 1",
|
||||||
)
|
)
|
||||||
cls.machines_srv_1 = machines.Srv.objects.create(
|
cls.machines_srv_1 = machines.Srv.objects.create(
|
||||||
service="machines_srv_1",
|
service="machines_srv_1",
|
||||||
|
@ -398,7 +386,7 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
cls.machines_ipv6list_1 = machines.Ipv6List.objects.create(
|
cls.machines_ipv6list_1 = machines.Ipv6List.objects.create(
|
||||||
ipv6="2001:db8:1234::",
|
ipv6="2001:db8:1234::",
|
||||||
interface=cls.machines_interface_1, # Dep machines.Interface
|
interface=cls.machines_interface_1, # Dep machines.Interface
|
||||||
slaac_ip=False
|
slaac_ip=False,
|
||||||
)
|
)
|
||||||
cls.machines_service_1 = machines.Service.objects.create(
|
cls.machines_service_1 = machines.Service.objects.create(
|
||||||
service_type="machines_service_1",
|
service_type="machines_service_1",
|
||||||
|
@ -410,45 +398,45 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
service=cls.machines_service_1, # Dep machines.Service
|
service=cls.machines_service_1, # Dep machines.Service
|
||||||
server=cls.machines_interface_1, # Dep machines.Interface
|
server=cls.machines_interface_1, # Dep machines.Interface
|
||||||
last_regen=datetime.datetime.now(datetime.timezone.utc),
|
last_regen=datetime.datetime.now(datetime.timezone.utc),
|
||||||
asked_regen=False
|
asked_regen=False,
|
||||||
)
|
)
|
||||||
cls.machines_ouvertureport_1 = machines.OuverturePort.objects.create(
|
cls.machines_ouvertureport_1 = machines.OuverturePort.objects.create(
|
||||||
begin=1,
|
begin=1,
|
||||||
end=2,
|
end=2,
|
||||||
port_list=cls.machines_ouvertureportlist_1, # Dep machines.OuverturePortList
|
port_list=cls.machines_ouvertureportlist_1, # Dep machines.OuverturePortList
|
||||||
protocole=machines.OuverturePort.TCP,
|
protocole=machines.OuverturePort.TCP,
|
||||||
io=machines.OuverturePort.OUT
|
io=machines.OuverturePort.OUT,
|
||||||
)
|
)
|
||||||
cls.machines_nas_1 = machines.Nas.objects.create(
|
cls.machines_nas_1 = machines.Nas.objects.create(
|
||||||
name="machines_nas_1",
|
name="machines_nas_1",
|
||||||
nas_type=cls.machines_machinetype_1, # Dep machines.MachineType
|
nas_type=cls.machines_machinetype_1, # Dep machines.MachineType
|
||||||
machine_type=cls.machines_machinetype_1, # Dep machines.MachineType
|
machine_type=cls.machines_machinetype_1, # Dep machines.MachineType
|
||||||
port_access_mode=machines.Nas.AUTH[0][0],
|
port_access_mode=machines.Nas.AUTH[0][0],
|
||||||
autocapture_mac=False
|
autocapture_mac=False,
|
||||||
)
|
)
|
||||||
cls.preferences_service_1 = preferences.Service.objects.create(
|
cls.preferences_service_1 = preferences.Service.objects.create(
|
||||||
name="preferences_service_1",
|
name="preferences_service_1",
|
||||||
url="https://example.net",
|
url="https://example.net",
|
||||||
description="preferences Service 1",
|
description="preferences Service 1",
|
||||||
image="/media/logo/none.png"
|
image="/media/logo/none.png",
|
||||||
)
|
)
|
||||||
cls.topologie_stack_1 = topologie.Stack.objects.create(
|
cls.topologie_stack_1 = topologie.Stack.objects.create(
|
||||||
name="topologie_stack_1",
|
name="topologie_stack_1",
|
||||||
stack_id="1",
|
stack_id="1",
|
||||||
details="topologie Stack 1",
|
details="topologie Stack 1",
|
||||||
member_id_min=1,
|
member_id_min=1,
|
||||||
member_id_max=10
|
member_id_max=10,
|
||||||
)
|
)
|
||||||
cls.topologie_accespoint_1 = topologie.AccessPoint.objects.create(
|
cls.topologie_accespoint_1 = topologie.AccessPoint.objects.create(
|
||||||
user=cls.users_user_1, # Dep users.User
|
user=cls.users_user_1, # Dep users.User
|
||||||
name="machines_machine_1",
|
name="machines_machine_1",
|
||||||
active=True,
|
active=True,
|
||||||
location="topologie AccessPoint 1"
|
location="topologie AccessPoint 1",
|
||||||
)
|
)
|
||||||
cls.topologie_server_1 = topologie.Server.objects.create(
|
cls.topologie_server_1 = topologie.Server.objects.create(
|
||||||
user=cls.users_user_1, # Dep users.User
|
user=cls.users_user_1, # Dep users.User
|
||||||
name="machines_machine_1",
|
name="machines_machine_1",
|
||||||
active=True
|
active=True,
|
||||||
)
|
)
|
||||||
cls.topologie_building_1 = topologie.Building.objects.create(
|
cls.topologie_building_1 = topologie.Building.objects.create(
|
||||||
name="topologie_building_1"
|
name="topologie_building_1"
|
||||||
|
@ -456,14 +444,14 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
cls.topologie_switchbay_1 = topologie.SwitchBay.objects.create(
|
cls.topologie_switchbay_1 = topologie.SwitchBay.objects.create(
|
||||||
name="topologie_switchbay_1",
|
name="topologie_switchbay_1",
|
||||||
building=cls.topologie_building_1, # Dep topologie.Building
|
building=cls.topologie_building_1, # Dep topologie.Building
|
||||||
info="topologie SwitchBay 1"
|
info="topologie SwitchBay 1",
|
||||||
)
|
)
|
||||||
cls.topologie_constructorswitch_1 = topologie.ConstructorSwitch.objects.create(
|
cls.topologie_constructorswitch_1 = topologie.ConstructorSwitch.objects.create(
|
||||||
name="topologie_constructorswitch_1"
|
name="topologie_constructorswitch_1"
|
||||||
)
|
)
|
||||||
cls.topologie_modelswitch_1 = topologie.ModelSwitch.objects.create(
|
cls.topologie_modelswitch_1 = topologie.ModelSwitch.objects.create(
|
||||||
reference="topologie_modelswitch_1",
|
reference="topologie_modelswitch_1",
|
||||||
constructor=cls.topologie_constructorswitch_1 # Dep topologie.ConstructorSwitch
|
constructor=cls.topologie_constructorswitch_1, # Dep topologie.ConstructorSwitch
|
||||||
)
|
)
|
||||||
cls.topologie_switch_1 = topologie.Switch.objects.create(
|
cls.topologie_switch_1 = topologie.Switch.objects.create(
|
||||||
user=cls.users_user_1, # Dep users.User
|
user=cls.users_user_1, # Dep users.User
|
||||||
|
@ -473,11 +461,10 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
stack=cls.topologie_stack_1, # Dep topologie.Stack
|
stack=cls.topologie_stack_1, # Dep topologie.Stack
|
||||||
stack_member_id=1,
|
stack_member_id=1,
|
||||||
model=cls.topologie_modelswitch_1, # Dep topologie.ModelSwitch
|
model=cls.topologie_modelswitch_1, # Dep topologie.ModelSwitch
|
||||||
switchbay=cls.topologie_switchbay_1 # Dep topologie.SwitchBay
|
switchbay=cls.topologie_switchbay_1, # Dep topologie.SwitchBay
|
||||||
)
|
)
|
||||||
cls.topologie_room_1 = topologie.Room.objects.create(
|
cls.topologie_room_1 = topologie.Room.objects.create(
|
||||||
name="topologie_romm_1",
|
name="topologie_romm_1", details="topologie Room 1"
|
||||||
details="topologie Room 1"
|
|
||||||
)
|
)
|
||||||
cls.topologie_port_1 = topologie.Port.objects.create(
|
cls.topologie_port_1 = topologie.Port.objects.create(
|
||||||
switch=cls.topologie_switch_1, # Dep topologie.Switch
|
switch=cls.topologie_switch_1, # Dep topologie.Switch
|
||||||
|
@ -485,7 +472,7 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
room=cls.topologie_room_1, # Dep topologie.Room
|
room=cls.topologie_room_1, # Dep topologie.Room
|
||||||
radius=topologie.Port.STATES[0][0],
|
radius=topologie.Port.STATES[0][0],
|
||||||
vlan_force=cls.machines_vlan_1, # Dep machines.Vlan
|
vlan_force=cls.machines_vlan_1, # Dep machines.Vlan
|
||||||
details="topologie_switch_1"
|
details="topologie_switch_1",
|
||||||
)
|
)
|
||||||
cls.topologie_port_2 = topologie.Port.objects.create(
|
cls.topologie_port_2 = topologie.Port.objects.create(
|
||||||
switch=cls.topologie_switch_1, # Dep topologie.Switch
|
switch=cls.topologie_switch_1, # Dep topologie.Switch
|
||||||
|
@ -493,7 +480,7 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
machine_interface=cls.machines_interface_1, # Dep machines.Interface
|
machine_interface=cls.machines_interface_1, # Dep machines.Interface
|
||||||
radius=topologie.Port.STATES[0][0],
|
radius=topologie.Port.STATES[0][0],
|
||||||
vlan_force=cls.machines_vlan_1, # Dep machines.Vlan
|
vlan_force=cls.machines_vlan_1, # Dep machines.Vlan
|
||||||
details="topologie_switch_1"
|
details="topologie_switch_1",
|
||||||
)
|
)
|
||||||
cls.topologie_port_3 = topologie.Port.objects.create(
|
cls.topologie_port_3 = topologie.Port.objects.create(
|
||||||
switch=cls.topologie_switch_1, # Dep topologie.Switch
|
switch=cls.topologie_switch_1, # Dep topologie.Switch
|
||||||
|
@ -501,14 +488,15 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
room=cls.topologie_room_1, # Dep topologie.Room
|
room=cls.topologie_room_1, # Dep topologie.Room
|
||||||
radius=topologie.Port.STATES[0][0],
|
radius=topologie.Port.STATES[0][0],
|
||||||
# Do not defines related because circular dependency # Dep machines.Vlan
|
# Do not defines related because circular dependency # Dep machines.Vlan
|
||||||
details="topologie_switch_1"
|
details="topologie_switch_1",
|
||||||
)
|
)
|
||||||
cls.users_ban_1 = users.Ban.objects.create(
|
cls.users_ban_1 = users.Ban.objects.create(
|
||||||
user=cls.users_user_1, # Dep users.User
|
user=cls.users_user_1, # Dep users.User
|
||||||
raison="users Ban 1",
|
raison="users Ban 1",
|
||||||
date_start=datetime.datetime.now(datetime.timezone.utc),
|
date_start=datetime.datetime.now(datetime.timezone.utc),
|
||||||
date_end=datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(days=1),
|
date_end=datetime.datetime.now(datetime.timezone.utc)
|
||||||
state=users.Ban.STATES[0][0]
|
+ datetime.timedelta(days=1),
|
||||||
|
state=users.Ban.STATES[0][0],
|
||||||
)
|
)
|
||||||
cls.users_club_1 = users.Club.objects.create(
|
cls.users_club_1 = users.Club.objects.create(
|
||||||
password="password",
|
password="password",
|
||||||
|
@ -524,7 +512,7 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
registered=datetime.datetime.now(datetime.timezone.utc),
|
registered=datetime.datetime.now(datetime.timezone.utc),
|
||||||
telephone="0123456789",
|
telephone="0123456789",
|
||||||
uid_number=21103,
|
uid_number=21103,
|
||||||
rezo_rez_uid=21103
|
rezo_rez_uid=21103,
|
||||||
)
|
)
|
||||||
# Need merge of MR145 to work
|
# Need merge of MR145 to work
|
||||||
# TODO: Merge !145
|
# TODO: Merge !145
|
||||||
|
@ -539,17 +527,17 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
last_login=datetime.datetime.now(datetime.timezone.utc),
|
last_login=datetime.datetime.now(datetime.timezone.utc),
|
||||||
pseudo="usersserviceuser1",
|
pseudo="usersserviceuser1",
|
||||||
access_group=users.ServiceUser.ACCESS[0][0],
|
access_group=users.ServiceUser.ACCESS[0][0],
|
||||||
comment="users ServiceUser 1"
|
comment="users ServiceUser 1",
|
||||||
)
|
)
|
||||||
cls.users_whitelist_1 = users.Whitelist.objects.create(
|
cls.users_whitelist_1 = users.Whitelist.objects.create(
|
||||||
user=cls.users_user_1,
|
user=cls.users_user_1,
|
||||||
raison="users Whitelist 1",
|
raison="users Whitelist 1",
|
||||||
date_start=datetime.datetime.now(datetime.timezone.utc),
|
date_start=datetime.datetime.now(datetime.timezone.utc),
|
||||||
date_end=datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(days=1)
|
date_end=datetime.datetime.now(datetime.timezone.utc)
|
||||||
|
+ datetime.timedelta(days=1),
|
||||||
)
|
)
|
||||||
|
|
||||||
def check_responses_code(self, urls, expected_code, formats=None,
|
def check_responses_code(self, urls, expected_code, formats=None, assert_more=None):
|
||||||
assert_more=None):
|
|
||||||
"""Utility function to test if a list of urls answer an expected code.
|
"""Utility function to test if a list of urls answer an expected code.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -665,17 +653,20 @@ class APIEndpointsTestCase(APITestCase):
|
||||||
"""
|
"""
|
||||||
self.client.force_authenticate(user=self.superuser)
|
self.client.force_authenticate(user=self.superuser)
|
||||||
|
|
||||||
urls = self.no_auth_endpoints + self.auth_no_perm_endpoints + \
|
urls = (
|
||||||
self.auth_perm_endpoints
|
self.no_auth_endpoints
|
||||||
|
+ self.auth_no_perm_endpoints
|
||||||
|
+ self.auth_perm_endpoints
|
||||||
|
)
|
||||||
|
|
||||||
def assert_more(response, url, format):
|
def assert_more(response, url, format):
|
||||||
"""Assert the response is valid json when format is json"""
|
"""Assert the response is valid json when format is json"""
|
||||||
if format is 'json':
|
if format is "json":
|
||||||
json.loads(response.content.decode())
|
json.loads(response.content.decode())
|
||||||
|
|
||||||
self.check_responses_code(urls, codes.ok,
|
self.check_responses_code(
|
||||||
formats=[None, 'json', 'api'],
|
urls, codes.ok, formats=[None, "json", "api"], assert_more=assert_more
|
||||||
assert_more=assert_more)
|
)
|
||||||
|
|
||||||
|
|
||||||
class APIPaginationTestCase(APITestCase):
|
class APIPaginationTestCase(APITestCase):
|
||||||
|
@ -688,56 +679,56 @@ class APIPaginationTestCase(APITestCase):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
endpoints = [
|
endpoints = [
|
||||||
'/api/cotisations/article/',
|
"/api/cotisations/article/",
|
||||||
'/api/cotisations/banque/',
|
"/api/cotisations/banque/",
|
||||||
'/api/cotisations/cotisation/',
|
"/api/cotisations/cotisation/",
|
||||||
'/api/cotisations/facture/',
|
"/api/cotisations/facture/",
|
||||||
'/api/cotisations/paiement/',
|
"/api/cotisations/paiement/",
|
||||||
'/api/cotisations/vente/',
|
"/api/cotisations/vente/",
|
||||||
'/api/machines/domain/',
|
"/api/machines/domain/",
|
||||||
'/api/machines/extension/',
|
"/api/machines/extension/",
|
||||||
'/api/machines/interface/',
|
"/api/machines/interface/",
|
||||||
'/api/machines/iplist/',
|
"/api/machines/iplist/",
|
||||||
'/api/machines/iptype/',
|
"/api/machines/iptype/",
|
||||||
'/api/machines/ipv6list/',
|
"/api/machines/ipv6list/",
|
||||||
'/api/machines/machine/',
|
"/api/machines/machine/",
|
||||||
'/api/machines/machinetype/',
|
"/api/machines/machinetype/",
|
||||||
'/api/machines/mx/',
|
"/api/machines/mx/",
|
||||||
'/api/machines/nas/',
|
"/api/machines/nas/",
|
||||||
'/api/machines/ns/',
|
"/api/machines/ns/",
|
||||||
'/api/machines/ouvertureportlist/',
|
"/api/machines/ouvertureportlist/",
|
||||||
'/api/machines/ouvertureport/',
|
"/api/machines/ouvertureport/",
|
||||||
'/api/machines/servicelink/',
|
"/api/machines/servicelink/",
|
||||||
'/api/machines/service/',
|
"/api/machines/service/",
|
||||||
'/api/machines/soa/',
|
"/api/machines/soa/",
|
||||||
'/api/machines/srv/',
|
"/api/machines/srv/",
|
||||||
'/api/machines/txt/',
|
"/api/machines/txt/",
|
||||||
'/api/machines/vlan/',
|
"/api/machines/vlan/",
|
||||||
'/api/preferences/service/',
|
"/api/preferences/service/",
|
||||||
'/api/topologie/acesspoint/',
|
"/api/topologie/acesspoint/",
|
||||||
'/api/topologie/building/',
|
"/api/topologie/building/",
|
||||||
'/api/topologie/constructorswitch/',
|
"/api/topologie/constructorswitch/",
|
||||||
'/api/topologie/modelswitch/',
|
"/api/topologie/modelswitch/",
|
||||||
'/api/topologie/room/',
|
"/api/topologie/room/",
|
||||||
'/api/topologie/server/',
|
"/api/topologie/server/",
|
||||||
'/api/topologie/stack/',
|
"/api/topologie/stack/",
|
||||||
'/api/topologie/switch/',
|
"/api/topologie/switch/",
|
||||||
'/api/topologie/switchbay/',
|
"/api/topologie/switchbay/",
|
||||||
'/api/topologie/switchport/',
|
"/api/topologie/switchport/",
|
||||||
'/api/users/adherent/',
|
"/api/users/adherent/",
|
||||||
'/api/users/ban/',
|
"/api/users/ban/",
|
||||||
'/api/users/club/',
|
"/api/users/club/",
|
||||||
'/api/users/listright/',
|
"/api/users/listright/",
|
||||||
'/api/users/school/',
|
"/api/users/school/",
|
||||||
'/api/users/serviceuser/',
|
"/api/users/serviceuser/",
|
||||||
'/api/users/shell/',
|
"/api/users/shell/",
|
||||||
'/api/users/user/',
|
"/api/users/user/",
|
||||||
'/api/users/whitelist/',
|
"/api/users/whitelist/",
|
||||||
'/api/dns/zones/',
|
"/api/dns/zones/",
|
||||||
'/api/dhcp/hostmacip/',
|
"/api/dhcp/hostmacip/",
|
||||||
'/api/mailing/standard',
|
"/api/mailing/standard",
|
||||||
'/api/mailing/club',
|
"/api/mailing/club",
|
||||||
'/api/services/regen/',
|
"/api/services/regen/",
|
||||||
]
|
]
|
||||||
superuser = None
|
superuser = None
|
||||||
|
|
||||||
|
@ -745,14 +736,14 @@ class APIPaginationTestCase(APITestCase):
|
||||||
def setUpTestData(cls):
|
def setUpTestData(cls):
|
||||||
# A user with all the rights
|
# A user with all the rights
|
||||||
# We need to use a different username than for the first
|
# 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
|
# trigger the ldap_sync() thus the LDAP still have data about
|
||||||
# the old users.
|
# the old users.
|
||||||
cls.superuser = users.User.objects.create_superuser(
|
cls.superuser = users.User.objects.create_superuser(
|
||||||
"apisuperuser2",
|
"apisuperuser2",
|
||||||
"apisuperuser2",
|
"apisuperuser2",
|
||||||
"apisuperuser2@example.net",
|
"apisuperuser2@example.net",
|
||||||
"apisuperuser2"
|
"apisuperuser2",
|
||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -771,10 +762,10 @@ class APIPaginationTestCase(APITestCase):
|
||||||
self.client.force_authenticate(self.superuser)
|
self.client.force_authenticate(self.superuser)
|
||||||
for url in self.endpoints:
|
for url in self.endpoints:
|
||||||
with self.subTest(url=url):
|
with self.subTest(url=url):
|
||||||
response = self.client.get(url, format='json')
|
response = self.client.get(url, format="json")
|
||||||
res_json = json.loads(response.content.decode())
|
res_json = json.loads(response.content.decode())
|
||||||
assert 'count' in res_json.keys()
|
assert "count" in res_json.keys()
|
||||||
assert 'next' in res_json.keys()
|
assert "next" in res_json.keys()
|
||||||
assert 'previous' in res_json.keys()
|
assert "previous" in res_json.keys()
|
||||||
assert 'results' in res_json.keys()
|
assert "results" in res_json.keys()
|
||||||
assert not len('results') > 100
|
assert not len("results") > 100
|
||||||
|
|
170
api/urls.py
170
api/urls.py
|
@ -34,95 +34,109 @@ from .routers import AllViewsRouter
|
||||||
|
|
||||||
router = AllViewsRouter()
|
router = AllViewsRouter()
|
||||||
# COTISATIONS
|
# COTISATIONS
|
||||||
router.register_viewset(r'cotisations/facture', views.FactureViewSet)
|
router.register_viewset(r"cotisations/facture", views.FactureViewSet)
|
||||||
router.register_viewset(r'cotisations/vente', views.VenteViewSet)
|
router.register_viewset(r"cotisations/vente", views.VenteViewSet)
|
||||||
router.register_viewset(r'cotisations/article', views.ArticleViewSet)
|
router.register_viewset(r"cotisations/article", views.ArticleViewSet)
|
||||||
router.register_viewset(r'cotisations/banque', views.BanqueViewSet)
|
router.register_viewset(r"cotisations/banque", views.BanqueViewSet)
|
||||||
router.register_viewset(r'cotisations/paiement', views.PaiementViewSet)
|
router.register_viewset(r"cotisations/paiement", views.PaiementViewSet)
|
||||||
router.register_viewset(r'cotisations/cotisation', views.CotisationViewSet)
|
router.register_viewset(r"cotisations/cotisation", views.CotisationViewSet)
|
||||||
# MACHINES
|
# MACHINES
|
||||||
router.register_viewset(r'machines/machine', views.MachineViewSet)
|
router.register_viewset(r"machines/machine", views.MachineViewSet)
|
||||||
router.register_viewset(r'machines/machinetype', views.MachineTypeViewSet)
|
router.register_viewset(r"machines/machinetype", views.MachineTypeViewSet)
|
||||||
router.register_viewset(r'machines/iptype', views.IpTypeViewSet)
|
router.register_viewset(r"machines/iptype", views.IpTypeViewSet)
|
||||||
router.register_viewset(r'machines/vlan', views.VlanViewSet)
|
router.register_viewset(r"machines/vlan", views.VlanViewSet)
|
||||||
router.register_viewset(r'machines/nas', views.NasViewSet)
|
router.register_viewset(r"machines/nas", views.NasViewSet)
|
||||||
router.register_viewset(r'machines/soa', views.SOAViewSet)
|
router.register_viewset(r"machines/soa", views.SOAViewSet)
|
||||||
router.register_viewset(r'machines/extension', views.ExtensionViewSet)
|
router.register_viewset(r"machines/extension", views.ExtensionViewSet)
|
||||||
router.register_viewset(r'machines/mx', views.MxViewSet)
|
router.register_viewset(r"machines/mx", views.MxViewSet)
|
||||||
router.register_viewset(r'machines/ns', views.NsViewSet)
|
router.register_viewset(r"machines/ns", views.NsViewSet)
|
||||||
router.register_viewset(r'machines/txt', views.TxtViewSet)
|
router.register_viewset(r"machines/txt", views.TxtViewSet)
|
||||||
router.register_viewset(r'machines/dname', views.DNameViewSet)
|
router.register_viewset(r"machines/dname", views.DNameViewSet)
|
||||||
router.register_viewset(r'machines/srv', views.SrvViewSet)
|
router.register_viewset(r"machines/srv", views.SrvViewSet)
|
||||||
router.register_viewset(r'machines/sshfp', views.SshFpViewSet)
|
router.register_viewset(r"machines/sshfp", views.SshFpViewSet)
|
||||||
router.register_viewset(r'machines/interface', views.InterfaceViewSet)
|
router.register_viewset(r"machines/interface", views.InterfaceViewSet)
|
||||||
router.register_viewset(r'machines/ipv6list', views.Ipv6ListViewSet)
|
router.register_viewset(r"machines/ipv6list", views.Ipv6ListViewSet)
|
||||||
router.register_viewset(r'machines/domain', views.DomainViewSet)
|
router.register_viewset(r"machines/domain", views.DomainViewSet)
|
||||||
router.register_viewset(r'machines/iplist', views.IpListViewSet)
|
router.register_viewset(r"machines/iplist", views.IpListViewSet)
|
||||||
router.register_viewset(r'machines/service', views.ServiceViewSet)
|
router.register_viewset(r"machines/service", views.ServiceViewSet)
|
||||||
router.register_viewset(r'machines/servicelink', views.ServiceLinkViewSet, base_name='servicelink')
|
router.register_viewset(
|
||||||
router.register_viewset(r'machines/ouvertureportlist', views.OuverturePortListViewSet)
|
r"machines/servicelink", views.ServiceLinkViewSet, base_name="servicelink"
|
||||||
router.register_viewset(r'machines/ouvertureport', views.OuverturePortViewSet)
|
)
|
||||||
router.register_viewset(r'machines/role', views.RoleViewSet)
|
router.register_viewset(r"machines/ouvertureportlist", views.OuverturePortListViewSet)
|
||||||
|
router.register_viewset(r"machines/ouvertureport", views.OuverturePortViewSet)
|
||||||
|
router.register_viewset(r"machines/role", views.RoleViewSet)
|
||||||
# PREFERENCES
|
# PREFERENCES
|
||||||
router.register_view(r'preferences/optionaluser', views.OptionalUserView),
|
router.register_view(r"preferences/optionaluser", views.OptionalUserView),
|
||||||
router.register_view(r'preferences/optionalmachine', views.OptionalMachineView),
|
router.register_view(r"preferences/optionalmachine", views.OptionalMachineView),
|
||||||
router.register_view(r'preferences/optionaltopologie', views.OptionalTopologieView),
|
router.register_view(r"preferences/optionaltopologie", views.OptionalTopologieView),
|
||||||
router.register_view(r'preferences/radiusoption', views.RadiusOptionView),
|
router.register_view(r"preferences/radiusoption", views.RadiusOptionView),
|
||||||
router.register_view(r'preferences/generaloption', views.GeneralOptionView),
|
router.register_view(r"preferences/generaloption", views.GeneralOptionView),
|
||||||
router.register_viewset(r'preferences/service', views.HomeServiceViewSet, base_name='homeservice'),
|
router.register_viewset(
|
||||||
router.register_view(r'preferences/assooption', views.AssoOptionView),
|
r"preferences/service", views.HomeServiceViewSet, base_name="homeservice"
|
||||||
router.register_view(r'preferences/homeoption', views.HomeOptionView),
|
),
|
||||||
router.register_view(r'preferences/mailmessageoption', views.MailMessageOptionView),
|
router.register_view(r"preferences/assooption", views.AssoOptionView),
|
||||||
|
router.register_view(r"preferences/homeoption", views.HomeOptionView),
|
||||||
|
router.register_view(r"preferences/mailmessageoption", views.MailMessageOptionView),
|
||||||
# TOPOLOGIE
|
# TOPOLOGIE
|
||||||
router.register_viewset(r'topologie/stack', views.StackViewSet)
|
router.register_viewset(r"topologie/stack", views.StackViewSet)
|
||||||
router.register_viewset(r'topologie/acesspoint', views.AccessPointViewSet)
|
router.register_viewset(r"topologie/acesspoint", views.AccessPointViewSet)
|
||||||
router.register_viewset(r'topologie/switch', views.SwitchViewSet)
|
router.register_viewset(r"topologie/switch", views.SwitchViewSet)
|
||||||
router.register_viewset(r'topologie/server', views.ServerViewSet)
|
router.register_viewset(r"topologie/server", views.ServerViewSet)
|
||||||
router.register_viewset(r'topologie/modelswitch', views.ModelSwitchViewSet)
|
router.register_viewset(r"topologie/modelswitch", views.ModelSwitchViewSet)
|
||||||
router.register_viewset(r'topologie/constructorswitch', views.ConstructorSwitchViewSet)
|
router.register_viewset(r"topologie/constructorswitch", views.ConstructorSwitchViewSet)
|
||||||
router.register_viewset(r'topologie/switchbay', views.SwitchBayViewSet)
|
router.register_viewset(r"topologie/switchbay", views.SwitchBayViewSet)
|
||||||
router.register_viewset(r'topologie/building', views.BuildingViewSet)
|
router.register_viewset(r"topologie/building", views.BuildingViewSet)
|
||||||
router.register_viewset(r'topologie/switchport', views.SwitchPortViewSet, base_name='switchport')
|
router.register_viewset(
|
||||||
router.register_viewset(r'topologie/portprofile', views.PortProfileViewSet, base_name='portprofile')
|
r"topologie/switchport", views.SwitchPortViewSet, base_name="switchport"
|
||||||
router.register_viewset(r'topologie/room', views.RoomViewSet)
|
)
|
||||||
router.register(r'topologie/portprofile', views.PortProfileViewSet)
|
router.register_viewset(
|
||||||
|
r"topologie/portprofile", views.PortProfileViewSet, base_name="portprofile"
|
||||||
|
)
|
||||||
|
router.register_viewset(r"topologie/room", views.RoomViewSet)
|
||||||
|
router.register(r"topologie/portprofile", views.PortProfileViewSet)
|
||||||
# USERS
|
# USERS
|
||||||
router.register_viewset(r'users/user', views.UserViewSet, base_name='user')
|
router.register_viewset(r"users/user", views.UserViewSet, base_name="user")
|
||||||
router.register_viewset(r'users/homecreation', views.HomeCreationViewSet, base_name='homecreation')
|
router.register_viewset(
|
||||||
router.register_viewset(r'users/normaluser', views.NormalUserViewSet, base_name='normaluser')
|
r"users/homecreation", views.HomeCreationViewSet, base_name="homecreation"
|
||||||
router.register_viewset(r'users/criticaluser', views.CriticalUserViewSet, base_name='criticaluser')
|
)
|
||||||
router.register_viewset(r'users/club', views.ClubViewSet)
|
router.register_viewset(
|
||||||
router.register_viewset(r'users/adherent', views.AdherentViewSet)
|
r"users/normaluser", views.NormalUserViewSet, base_name="normaluser"
|
||||||
router.register_viewset(r'users/serviceuser', views.ServiceUserViewSet)
|
)
|
||||||
router.register_viewset(r'users/school', views.SchoolViewSet)
|
router.register_viewset(
|
||||||
router.register_viewset(r'users/listright', views.ListRightViewSet)
|
r"users/criticaluser", views.CriticalUserViewSet, base_name="criticaluser"
|
||||||
router.register_viewset(r'users/shell', views.ShellViewSet, base_name='shell')
|
)
|
||||||
router.register_viewset(r'users/ban', views.BanViewSet)
|
router.register_viewset(r"users/club", views.ClubViewSet)
|
||||||
router.register_viewset(r'users/whitelist', views.WhitelistViewSet)
|
router.register_viewset(r"users/adherent", views.AdherentViewSet)
|
||||||
router.register_viewset(r'users/emailaddress', views.EMailAddressViewSet)
|
router.register_viewset(r"users/serviceuser", views.ServiceUserViewSet)
|
||||||
|
router.register_viewset(r"users/school", views.SchoolViewSet)
|
||||||
|
router.register_viewset(r"users/listright", views.ListRightViewSet)
|
||||||
|
router.register_viewset(r"users/shell", views.ShellViewSet, base_name="shell")
|
||||||
|
router.register_viewset(r"users/ban", views.BanViewSet)
|
||||||
|
router.register_viewset(r"users/whitelist", views.WhitelistViewSet)
|
||||||
|
router.register_viewset(r"users/emailaddress", views.EMailAddressViewSet)
|
||||||
# SERVICE REGEN
|
# SERVICE REGEN
|
||||||
router.register_viewset(r'services/regen', views.ServiceRegenViewSet, base_name='serviceregen')
|
router.register_viewset(
|
||||||
|
r"services/regen", views.ServiceRegenViewSet, base_name="serviceregen"
|
||||||
|
)
|
||||||
# DHCP
|
# DHCP
|
||||||
router.register_view(r'dhcp/hostmacip', views.HostMacIpView),
|
router.register_view(r"dhcp/hostmacip", views.HostMacIpView),
|
||||||
# LOCAL EMAILS
|
# LOCAL EMAILS
|
||||||
router.register_view(r'localemail/users', views.LocalEmailUsersView),
|
router.register_view(r"localemail/users", views.LocalEmailUsersView),
|
||||||
# Firewall
|
# Firewall
|
||||||
router.register_view(r'firewall/subnet-ports', views.SubnetPortsOpenView),
|
router.register_view(r"firewall/subnet-ports", views.SubnetPortsOpenView),
|
||||||
router.register_view(r'firewall/interface-ports', views.InterfacePortsOpenView),
|
router.register_view(r"firewall/interface-ports", views.InterfacePortsOpenView),
|
||||||
# Switches config
|
# Switches config
|
||||||
router.register_view(r'switchs/ports-config', views.SwitchPortView),
|
router.register_view(r"switchs/ports-config", views.SwitchPortView),
|
||||||
router.register_view(r'switchs/role', views.RoleView),
|
router.register_view(r"switchs/role", views.RoleView),
|
||||||
# Reminder
|
# Reminder
|
||||||
router.register_view(r'reminder/get-users', views.ReminderView),
|
router.register_view(r"reminder/get-users", views.ReminderView),
|
||||||
# DNS
|
# DNS
|
||||||
router.register_view(r'dns/zones', views.DNSZonesView),
|
router.register_view(r"dns/zones", views.DNSZonesView),
|
||||||
router.register_view(r'dns/reverse-zones', views.DNSReverseZonesView),
|
router.register_view(r"dns/reverse-zones", views.DNSReverseZonesView),
|
||||||
# MAILING
|
# MAILING
|
||||||
router.register_view(r'mailing/standard', views.StandardMailingView),
|
router.register_view(r"mailing/standard", views.StandardMailingView),
|
||||||
router.register_view(r'mailing/club', views.ClubMailingView),
|
router.register_view(r"mailing/club", views.ClubMailingView),
|
||||||
# TOKEN AUTHENTICATION
|
# TOKEN AUTHENTICATION
|
||||||
router.register_view(r'token-auth', views.ObtainExpiringAuthToken)
|
router.register_view(r"token-auth", views.ObtainExpiringAuthToken)
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [url(r"^", include(router.urls))]
|
||||||
url(r'^', include(router.urls)),
|
|
||||||
]
|
|
||||||
|
|
179
api/views.py
179
api/views.py
|
@ -52,12 +52,15 @@ from .permissions import ACLPermission
|
||||||
class FactureViewSet(viewsets.ReadOnlyModelViewSet):
|
class FactureViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `cotisations.models.Facture` objects.
|
"""Exposes list and details of `cotisations.models.Facture` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = cotisations.Facture.objects.all()
|
queryset = cotisations.Facture.objects.all()
|
||||||
serializer_class = serializers.FactureSerializer
|
serializer_class = serializers.FactureSerializer
|
||||||
|
|
||||||
|
|
||||||
class FactureViewSet(viewsets.ReadOnlyModelViewSet):
|
class FactureViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `cotisations.models.Facture` objects.
|
"""Exposes list and details of `cotisations.models.Facture` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = cotisations.BaseInvoice.objects.all()
|
queryset = cotisations.BaseInvoice.objects.all()
|
||||||
serializer_class = serializers.BaseInvoiceSerializer
|
serializer_class = serializers.BaseInvoiceSerializer
|
||||||
|
|
||||||
|
@ -65,6 +68,7 @@ class FactureViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class VenteViewSet(viewsets.ReadOnlyModelViewSet):
|
class VenteViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `cotisations.models.Vente` objects.
|
"""Exposes list and details of `cotisations.models.Vente` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = cotisations.Vente.objects.all()
|
queryset = cotisations.Vente.objects.all()
|
||||||
serializer_class = serializers.VenteSerializer
|
serializer_class = serializers.VenteSerializer
|
||||||
|
|
||||||
|
@ -72,6 +76,7 @@ class VenteViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class ArticleViewSet(viewsets.ReadOnlyModelViewSet):
|
class ArticleViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `cotisations.models.Article` objects.
|
"""Exposes list and details of `cotisations.models.Article` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = cotisations.Article.objects.all()
|
queryset = cotisations.Article.objects.all()
|
||||||
serializer_class = serializers.ArticleSerializer
|
serializer_class = serializers.ArticleSerializer
|
||||||
|
|
||||||
|
@ -79,6 +84,7 @@ class ArticleViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class BanqueViewSet(viewsets.ReadOnlyModelViewSet):
|
class BanqueViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `cotisations.models.Banque` objects.
|
"""Exposes list and details of `cotisations.models.Banque` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = cotisations.Banque.objects.all()
|
queryset = cotisations.Banque.objects.all()
|
||||||
serializer_class = serializers.BanqueSerializer
|
serializer_class = serializers.BanqueSerializer
|
||||||
|
|
||||||
|
@ -86,6 +92,7 @@ class BanqueViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class PaiementViewSet(viewsets.ReadOnlyModelViewSet):
|
class PaiementViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `cotisations.models.Paiement` objects.
|
"""Exposes list and details of `cotisations.models.Paiement` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = cotisations.Paiement.objects.all()
|
queryset = cotisations.Paiement.objects.all()
|
||||||
serializer_class = serializers.PaiementSerializer
|
serializer_class = serializers.PaiementSerializer
|
||||||
|
|
||||||
|
@ -93,6 +100,7 @@ class PaiementViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class CotisationViewSet(viewsets.ReadOnlyModelViewSet):
|
class CotisationViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `cotisations.models.Cotisation` objects.
|
"""Exposes list and details of `cotisations.models.Cotisation` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = cotisations.Cotisation.objects.all()
|
queryset = cotisations.Cotisation.objects.all()
|
||||||
serializer_class = serializers.CotisationSerializer
|
serializer_class = serializers.CotisationSerializer
|
||||||
|
|
||||||
|
@ -103,6 +111,7 @@ class CotisationViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class MachineViewSet(viewsets.ReadOnlyModelViewSet):
|
class MachineViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.Machine` objects.
|
"""Exposes list and details of `machines.models.Machine` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.Machine.objects.all()
|
queryset = machines.Machine.objects.all()
|
||||||
serializer_class = serializers.MachineSerializer
|
serializer_class = serializers.MachineSerializer
|
||||||
|
|
||||||
|
@ -110,6 +119,7 @@ class MachineViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class MachineTypeViewSet(viewsets.ReadOnlyModelViewSet):
|
class MachineTypeViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.MachineType` objects.
|
"""Exposes list and details of `machines.models.MachineType` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.MachineType.objects.all()
|
queryset = machines.MachineType.objects.all()
|
||||||
serializer_class = serializers.MachineTypeSerializer
|
serializer_class = serializers.MachineTypeSerializer
|
||||||
|
|
||||||
|
@ -117,6 +127,7 @@ class MachineTypeViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class IpTypeViewSet(viewsets.ReadOnlyModelViewSet):
|
class IpTypeViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.IpType` objects.
|
"""Exposes list and details of `machines.models.IpType` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.IpType.objects.all()
|
queryset = machines.IpType.objects.all()
|
||||||
serializer_class = serializers.IpTypeSerializer
|
serializer_class = serializers.IpTypeSerializer
|
||||||
|
|
||||||
|
@ -124,6 +135,7 @@ class IpTypeViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class VlanViewSet(viewsets.ReadOnlyModelViewSet):
|
class VlanViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.Vlan` objects.
|
"""Exposes list and details of `machines.models.Vlan` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.Vlan.objects.all()
|
queryset = machines.Vlan.objects.all()
|
||||||
serializer_class = serializers.VlanSerializer
|
serializer_class = serializers.VlanSerializer
|
||||||
|
|
||||||
|
@ -131,6 +143,7 @@ class VlanViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class NasViewSet(viewsets.ReadOnlyModelViewSet):
|
class NasViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.Nas` objects.
|
"""Exposes list and details of `machines.models.Nas` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.Nas.objects.all()
|
queryset = machines.Nas.objects.all()
|
||||||
serializer_class = serializers.NasSerializer
|
serializer_class = serializers.NasSerializer
|
||||||
|
|
||||||
|
@ -138,6 +151,7 @@ class NasViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class SOAViewSet(viewsets.ReadOnlyModelViewSet):
|
class SOAViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.SOA` objects.
|
"""Exposes list and details of `machines.models.SOA` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.SOA.objects.all()
|
queryset = machines.SOA.objects.all()
|
||||||
serializer_class = serializers.SOASerializer
|
serializer_class = serializers.SOASerializer
|
||||||
|
|
||||||
|
@ -145,6 +159,7 @@ class SOAViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class ExtensionViewSet(viewsets.ReadOnlyModelViewSet):
|
class ExtensionViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.Extension` objects.
|
"""Exposes list and details of `machines.models.Extension` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.Extension.objects.all()
|
queryset = machines.Extension.objects.all()
|
||||||
serializer_class = serializers.ExtensionSerializer
|
serializer_class = serializers.ExtensionSerializer
|
||||||
|
|
||||||
|
@ -152,6 +167,7 @@ class ExtensionViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class MxViewSet(viewsets.ReadOnlyModelViewSet):
|
class MxViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.Mx` objects.
|
"""Exposes list and details of `machines.models.Mx` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.Mx.objects.all()
|
queryset = machines.Mx.objects.all()
|
||||||
serializer_class = serializers.MxSerializer
|
serializer_class = serializers.MxSerializer
|
||||||
|
|
||||||
|
@ -159,6 +175,7 @@ class MxViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class NsViewSet(viewsets.ReadOnlyModelViewSet):
|
class NsViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.Ns` objects.
|
"""Exposes list and details of `machines.models.Ns` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.Ns.objects.all()
|
queryset = machines.Ns.objects.all()
|
||||||
serializer_class = serializers.NsSerializer
|
serializer_class = serializers.NsSerializer
|
||||||
|
|
||||||
|
@ -166,6 +183,7 @@ class NsViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class TxtViewSet(viewsets.ReadOnlyModelViewSet):
|
class TxtViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.Txt` objects.
|
"""Exposes list and details of `machines.models.Txt` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.Txt.objects.all()
|
queryset = machines.Txt.objects.all()
|
||||||
serializer_class = serializers.TxtSerializer
|
serializer_class = serializers.TxtSerializer
|
||||||
|
|
||||||
|
@ -173,6 +191,7 @@ class TxtViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class DNameViewSet(viewsets.ReadOnlyModelViewSet):
|
class DNameViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.DName` objects.
|
"""Exposes list and details of `machines.models.DName` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.DName.objects.all()
|
queryset = machines.DName.objects.all()
|
||||||
serializer_class = serializers.DNameSerializer
|
serializer_class = serializers.DNameSerializer
|
||||||
|
|
||||||
|
@ -180,6 +199,7 @@ class DNameViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class SrvViewSet(viewsets.ReadOnlyModelViewSet):
|
class SrvViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.Srv` objects.
|
"""Exposes list and details of `machines.models.Srv` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.Srv.objects.all()
|
queryset = machines.Srv.objects.all()
|
||||||
serializer_class = serializers.SrvSerializer
|
serializer_class = serializers.SrvSerializer
|
||||||
|
|
||||||
|
@ -187,6 +207,7 @@ class SrvViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class SshFpViewSet(viewsets.ReadOnlyModelViewSet):
|
class SshFpViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.SshFp` objects.
|
"""Exposes list and details of `machines.models.SshFp` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.SshFp.objects.all()
|
queryset = machines.SshFp.objects.all()
|
||||||
serializer_class = serializers.SshFpSerializer
|
serializer_class = serializers.SshFpSerializer
|
||||||
|
|
||||||
|
@ -194,6 +215,7 @@ class SshFpViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class InterfaceViewSet(viewsets.ReadOnlyModelViewSet):
|
class InterfaceViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.Interface` objects.
|
"""Exposes list and details of `machines.models.Interface` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.Interface.objects.all()
|
queryset = machines.Interface.objects.all()
|
||||||
serializer_class = serializers.InterfaceSerializer
|
serializer_class = serializers.InterfaceSerializer
|
||||||
|
|
||||||
|
@ -201,6 +223,7 @@ class InterfaceViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class Ipv6ListViewSet(viewsets.ReadOnlyModelViewSet):
|
class Ipv6ListViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.Ipv6List` objects.
|
"""Exposes list and details of `machines.models.Ipv6List` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.Ipv6List.objects.all()
|
queryset = machines.Ipv6List.objects.all()
|
||||||
serializer_class = serializers.Ipv6ListSerializer
|
serializer_class = serializers.Ipv6ListSerializer
|
||||||
|
|
||||||
|
@ -208,6 +231,7 @@ class Ipv6ListViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class DomainViewSet(viewsets.ReadOnlyModelViewSet):
|
class DomainViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.Domain` objects.
|
"""Exposes list and details of `machines.models.Domain` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.Domain.objects.all()
|
queryset = machines.Domain.objects.all()
|
||||||
serializer_class = serializers.DomainSerializer
|
serializer_class = serializers.DomainSerializer
|
||||||
|
|
||||||
|
@ -215,6 +239,7 @@ class DomainViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class IpListViewSet(viewsets.ReadOnlyModelViewSet):
|
class IpListViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.IpList` objects.
|
"""Exposes list and details of `machines.models.IpList` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.IpList.objects.all()
|
queryset = machines.IpList.objects.all()
|
||||||
serializer_class = serializers.IpListSerializer
|
serializer_class = serializers.IpListSerializer
|
||||||
|
|
||||||
|
@ -222,6 +247,7 @@ class IpListViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class ServiceViewSet(viewsets.ReadOnlyModelViewSet):
|
class ServiceViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.Service` objects.
|
"""Exposes list and details of `machines.models.Service` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.Service.objects.all()
|
queryset = machines.Service.objects.all()
|
||||||
serializer_class = serializers.ServiceSerializer
|
serializer_class = serializers.ServiceSerializer
|
||||||
|
|
||||||
|
@ -229,6 +255,7 @@ class ServiceViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class ServiceLinkViewSet(viewsets.ReadOnlyModelViewSet):
|
class ServiceLinkViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.Service_link` objects.
|
"""Exposes list and details of `machines.models.Service_link` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.Service_link.objects.all()
|
queryset = machines.Service_link.objects.all()
|
||||||
serializer_class = serializers.ServiceLinkSerializer
|
serializer_class = serializers.ServiceLinkSerializer
|
||||||
|
|
||||||
|
@ -237,6 +264,7 @@ class OuverturePortListViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.OuverturePortList`
|
"""Exposes list and details of `machines.models.OuverturePortList`
|
||||||
objects.
|
objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.OuverturePortList.objects.all()
|
queryset = machines.OuverturePortList.objects.all()
|
||||||
serializer_class = serializers.OuverturePortListSerializer
|
serializer_class = serializers.OuverturePortListSerializer
|
||||||
|
|
||||||
|
@ -244,6 +272,7 @@ class OuverturePortListViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class OuverturePortViewSet(viewsets.ReadOnlyModelViewSet):
|
class OuverturePortViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.OuverturePort` objects.
|
"""Exposes list and details of `machines.models.OuverturePort` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.OuverturePort.objects.all()
|
queryset = machines.OuverturePort.objects.all()
|
||||||
serializer_class = serializers.OuverturePortSerializer
|
serializer_class = serializers.OuverturePortSerializer
|
||||||
|
|
||||||
|
@ -251,6 +280,7 @@ class OuverturePortViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class RoleViewSet(viewsets.ReadOnlyModelViewSet):
|
class RoleViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `machines.models.Machine` objects.
|
"""Exposes list and details of `machines.models.Machine` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = machines.Role.objects.all()
|
queryset = machines.Role.objects.all()
|
||||||
serializer_class = serializers.RoleSerializer
|
serializer_class = serializers.RoleSerializer
|
||||||
|
|
||||||
|
@ -259,11 +289,13 @@ class RoleViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
# Those views differ a bit because there is only one object
|
# Those views differ a bit because there is only one object
|
||||||
# to display, so we don't bother with the listing part
|
# to display, so we don't bother with the listing part
|
||||||
|
|
||||||
|
|
||||||
class OptionalUserView(generics.RetrieveAPIView):
|
class OptionalUserView(generics.RetrieveAPIView):
|
||||||
"""Exposes details of `preferences.models.` settings.
|
"""Exposes details of `preferences.models.` settings.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
permission_classes = (ACLPermission,)
|
permission_classes = (ACLPermission,)
|
||||||
perms_map = {'GET': [preferences.OptionalUser.can_view_all]}
|
perms_map = {"GET": [preferences.OptionalUser.can_view_all]}
|
||||||
serializer_class = serializers.OptionalUserSerializer
|
serializer_class = serializers.OptionalUserSerializer
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
|
@ -273,8 +305,9 @@ class OptionalUserView(generics.RetrieveAPIView):
|
||||||
class OptionalMachineView(generics.RetrieveAPIView):
|
class OptionalMachineView(generics.RetrieveAPIView):
|
||||||
"""Exposes details of `preferences.models.OptionalMachine` settings.
|
"""Exposes details of `preferences.models.OptionalMachine` settings.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
permission_classes = (ACLPermission,)
|
permission_classes = (ACLPermission,)
|
||||||
perms_map = {'GET': [preferences.OptionalMachine.can_view_all]}
|
perms_map = {"GET": [preferences.OptionalMachine.can_view_all]}
|
||||||
serializer_class = serializers.OptionalMachineSerializer
|
serializer_class = serializers.OptionalMachineSerializer
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
|
@ -284,8 +317,9 @@ class OptionalMachineView(generics.RetrieveAPIView):
|
||||||
class OptionalTopologieView(generics.RetrieveAPIView):
|
class OptionalTopologieView(generics.RetrieveAPIView):
|
||||||
"""Exposes details of `preferences.models.OptionalTopologie` settings.
|
"""Exposes details of `preferences.models.OptionalTopologie` settings.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
permission_classes = (ACLPermission,)
|
permission_classes = (ACLPermission,)
|
||||||
perms_map = {'GET': [preferences.OptionalTopologie.can_view_all]}
|
perms_map = {"GET": [preferences.OptionalTopologie.can_view_all]}
|
||||||
serializer_class = serializers.OptionalTopologieSerializer
|
serializer_class = serializers.OptionalTopologieSerializer
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
|
@ -295,8 +329,9 @@ class OptionalTopologieView(generics.RetrieveAPIView):
|
||||||
class RadiusOptionView(generics.RetrieveAPIView):
|
class RadiusOptionView(generics.RetrieveAPIView):
|
||||||
"""Exposes details of `preferences.models.OptionalTopologie` settings.
|
"""Exposes details of `preferences.models.OptionalTopologie` settings.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
permission_classes = (ACLPermission,)
|
permission_classes = (ACLPermission,)
|
||||||
perms_map = {'GET': [preferences.RadiusOption.can_view_all]}
|
perms_map = {"GET": [preferences.RadiusOption.can_view_all]}
|
||||||
serializer_class = serializers.RadiusOptionSerializer
|
serializer_class = serializers.RadiusOptionSerializer
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
|
@ -306,8 +341,9 @@ class RadiusOptionView(generics.RetrieveAPIView):
|
||||||
class GeneralOptionView(generics.RetrieveAPIView):
|
class GeneralOptionView(generics.RetrieveAPIView):
|
||||||
"""Exposes details of `preferences.models.GeneralOption` settings.
|
"""Exposes details of `preferences.models.GeneralOption` settings.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
permission_classes = (ACLPermission,)
|
permission_classes = (ACLPermission,)
|
||||||
perms_map = {'GET': [preferences.GeneralOption.can_view_all]}
|
perms_map = {"GET": [preferences.GeneralOption.can_view_all]}
|
||||||
serializer_class = serializers.GeneralOptionSerializer
|
serializer_class = serializers.GeneralOptionSerializer
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
|
@ -317,6 +353,7 @@ class GeneralOptionView(generics.RetrieveAPIView):
|
||||||
class HomeServiceViewSet(viewsets.ReadOnlyModelViewSet):
|
class HomeServiceViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `preferences.models.Service` objects.
|
"""Exposes list and details of `preferences.models.Service` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = preferences.Service.objects.all()
|
queryset = preferences.Service.objects.all()
|
||||||
serializer_class = serializers.HomeServiceSerializer
|
serializer_class = serializers.HomeServiceSerializer
|
||||||
|
|
||||||
|
@ -324,8 +361,9 @@ class HomeServiceViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class AssoOptionView(generics.RetrieveAPIView):
|
class AssoOptionView(generics.RetrieveAPIView):
|
||||||
"""Exposes details of `preferences.models.AssoOption` settings.
|
"""Exposes details of `preferences.models.AssoOption` settings.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
permission_classes = (ACLPermission,)
|
permission_classes = (ACLPermission,)
|
||||||
perms_map = {'GET': [preferences.AssoOption.can_view_all]}
|
perms_map = {"GET": [preferences.AssoOption.can_view_all]}
|
||||||
serializer_class = serializers.AssoOptionSerializer
|
serializer_class = serializers.AssoOptionSerializer
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
|
@ -335,8 +373,9 @@ class AssoOptionView(generics.RetrieveAPIView):
|
||||||
class HomeOptionView(generics.RetrieveAPIView):
|
class HomeOptionView(generics.RetrieveAPIView):
|
||||||
"""Exposes details of `preferences.models.HomeOption` settings.
|
"""Exposes details of `preferences.models.HomeOption` settings.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
permission_classes = (ACLPermission,)
|
permission_classes = (ACLPermission,)
|
||||||
perms_map = {'GET': [preferences.HomeOption.can_view_all]}
|
perms_map = {"GET": [preferences.HomeOption.can_view_all]}
|
||||||
serializer_class = serializers.HomeOptionSerializer
|
serializer_class = serializers.HomeOptionSerializer
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
|
@ -346,8 +385,9 @@ class HomeOptionView(generics.RetrieveAPIView):
|
||||||
class MailMessageOptionView(generics.RetrieveAPIView):
|
class MailMessageOptionView(generics.RetrieveAPIView):
|
||||||
"""Exposes details of `preferences.models.MailMessageOption` settings.
|
"""Exposes details of `preferences.models.MailMessageOption` settings.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
permission_classes = (ACLPermission,)
|
permission_classes = (ACLPermission,)
|
||||||
perms_map = {'GET': [preferences.MailMessageOption.can_view_all]}
|
perms_map = {"GET": [preferences.MailMessageOption.can_view_all]}
|
||||||
serializer_class = serializers.MailMessageOptionSerializer
|
serializer_class = serializers.MailMessageOptionSerializer
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
|
@ -360,6 +400,7 @@ class MailMessageOptionView(generics.RetrieveAPIView):
|
||||||
class StackViewSet(viewsets.ReadOnlyModelViewSet):
|
class StackViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `topologie.models.Stack` objects.
|
"""Exposes list and details of `topologie.models.Stack` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = topologie.Stack.objects.all()
|
queryset = topologie.Stack.objects.all()
|
||||||
serializer_class = serializers.StackSerializer
|
serializer_class = serializers.StackSerializer
|
||||||
|
|
||||||
|
@ -367,6 +408,7 @@ class StackViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class AccessPointViewSet(viewsets.ReadOnlyModelViewSet):
|
class AccessPointViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `topologie.models.AccessPoint` objects.
|
"""Exposes list and details of `topologie.models.AccessPoint` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = topologie.AccessPoint.objects.all()
|
queryset = topologie.AccessPoint.objects.all()
|
||||||
serializer_class = serializers.AccessPointSerializer
|
serializer_class = serializers.AccessPointSerializer
|
||||||
|
|
||||||
|
@ -374,6 +416,7 @@ class AccessPointViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class SwitchViewSet(viewsets.ReadOnlyModelViewSet):
|
class SwitchViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `topologie.models.Switch` objects.
|
"""Exposes list and details of `topologie.models.Switch` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = topologie.Switch.objects.all()
|
queryset = topologie.Switch.objects.all()
|
||||||
serializer_class = serializers.SwitchSerializer
|
serializer_class = serializers.SwitchSerializer
|
||||||
|
|
||||||
|
@ -381,6 +424,7 @@ class SwitchViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class ServerViewSet(viewsets.ReadOnlyModelViewSet):
|
class ServerViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `topologie.models.Server` objects.
|
"""Exposes list and details of `topologie.models.Server` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = topologie.Server.objects.all()
|
queryset = topologie.Server.objects.all()
|
||||||
serializer_class = serializers.ServerSerializer
|
serializer_class = serializers.ServerSerializer
|
||||||
|
|
||||||
|
@ -388,6 +432,7 @@ class ServerViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class ModelSwitchViewSet(viewsets.ReadOnlyModelViewSet):
|
class ModelSwitchViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `topologie.models.ModelSwitch` objects.
|
"""Exposes list and details of `topologie.models.ModelSwitch` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = topologie.ModelSwitch.objects.all()
|
queryset = topologie.ModelSwitch.objects.all()
|
||||||
serializer_class = serializers.ModelSwitchSerializer
|
serializer_class = serializers.ModelSwitchSerializer
|
||||||
|
|
||||||
|
@ -396,6 +441,7 @@ class ConstructorSwitchViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `topologie.models.ConstructorSwitch`
|
"""Exposes list and details of `topologie.models.ConstructorSwitch`
|
||||||
objects.
|
objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = topologie.ConstructorSwitch.objects.all()
|
queryset = topologie.ConstructorSwitch.objects.all()
|
||||||
serializer_class = serializers.ConstructorSwitchSerializer
|
serializer_class = serializers.ConstructorSwitchSerializer
|
||||||
|
|
||||||
|
@ -403,6 +449,7 @@ class ConstructorSwitchViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class SwitchBayViewSet(viewsets.ReadOnlyModelViewSet):
|
class SwitchBayViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `topologie.models.SwitchBay` objects.
|
"""Exposes list and details of `topologie.models.SwitchBay` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = topologie.SwitchBay.objects.all()
|
queryset = topologie.SwitchBay.objects.all()
|
||||||
serializer_class = serializers.SwitchBaySerializer
|
serializer_class = serializers.SwitchBaySerializer
|
||||||
|
|
||||||
|
@ -410,6 +457,7 @@ class SwitchBayViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class BuildingViewSet(viewsets.ReadOnlyModelViewSet):
|
class BuildingViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `topologie.models.Building` objects.
|
"""Exposes list and details of `topologie.models.Building` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = topologie.Building.objects.all()
|
queryset = topologie.Building.objects.all()
|
||||||
serializer_class = serializers.BuildingSerializer
|
serializer_class = serializers.BuildingSerializer
|
||||||
|
|
||||||
|
@ -417,6 +465,7 @@ class BuildingViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class SwitchPortViewSet(viewsets.ReadOnlyModelViewSet):
|
class SwitchPortViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `topologie.models.Port` objects.
|
"""Exposes list and details of `topologie.models.Port` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = topologie.Port.objects.all()
|
queryset = topologie.Port.objects.all()
|
||||||
serializer_class = serializers.SwitchPortSerializer
|
serializer_class = serializers.SwitchPortSerializer
|
||||||
|
|
||||||
|
@ -424,6 +473,7 @@ class SwitchPortViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class PortProfileViewSet(viewsets.ReadOnlyModelViewSet):
|
class PortProfileViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `topologie.models.PortProfile` objects.
|
"""Exposes list and details of `topologie.models.PortProfile` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = topologie.PortProfile.objects.all()
|
queryset = topologie.PortProfile.objects.all()
|
||||||
serializer_class = serializers.PortProfileSerializer
|
serializer_class = serializers.PortProfileSerializer
|
||||||
|
|
||||||
|
@ -431,6 +481,7 @@ class PortProfileViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class RoomViewSet(viewsets.ReadOnlyModelViewSet):
|
class RoomViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `topologie.models.Room` objects.
|
"""Exposes list and details of `topologie.models.Room` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = topologie.Room.objects.all()
|
queryset = topologie.Room.objects.all()
|
||||||
serializer_class = serializers.RoomSerializer
|
serializer_class = serializers.RoomSerializer
|
||||||
|
|
||||||
|
@ -438,6 +489,7 @@ class RoomViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class PortProfileViewSet(viewsets.ReadOnlyModelViewSet):
|
class PortProfileViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `topologie.models.PortProfile` objects.
|
"""Exposes list and details of `topologie.models.PortProfile` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = topologie.PortProfile.objects.all()
|
queryset = topologie.PortProfile.objects.all()
|
||||||
serializer_class = serializers.PortProfileSerializer
|
serializer_class = serializers.PortProfileSerializer
|
||||||
|
|
||||||
|
@ -448,6 +500,7 @@ class PortProfileViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class UserViewSet(viewsets.ReadOnlyModelViewSet):
|
class UserViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `users.models.Users` objects.
|
"""Exposes list and details of `users.models.Users` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = users.User.objects.all()
|
queryset = users.User.objects.all()
|
||||||
serializer_class = serializers.UserSerializer
|
serializer_class = serializers.UserSerializer
|
||||||
|
|
||||||
|
@ -455,18 +508,25 @@ class UserViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class HomeCreationViewSet(viewsets.ReadOnlyModelViewSet):
|
class HomeCreationViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes infos of `users.models.Users` objects to create homes.
|
"""Exposes infos of `users.models.Users` objects to create homes.
|
||||||
"""
|
"""
|
||||||
queryset = users.User.objects.exclude(Q(state=users.User.STATE_DISABLED) | Q(state=users.User.STATE_NOT_YET_ACTIVE))
|
|
||||||
|
queryset = users.User.objects.exclude(
|
||||||
|
Q(state=users.User.STATE_DISABLED)
|
||||||
|
| Q(state=users.User.STATE_NOT_YET_ACTIVE)
|
||||||
|
| Q(state=users.User.STATE_FULL_ARCHIVE)
|
||||||
|
)
|
||||||
serializer_class = serializers.BasicUserSerializer
|
serializer_class = serializers.BasicUserSerializer
|
||||||
|
|
||||||
|
|
||||||
class NormalUserViewSet(viewsets.ReadOnlyModelViewSet):
|
class NormalUserViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes infos of `users.models.Users`without specific rights objects."""
|
"""Exposes infos of `users.models.Users`without specific rights objects."""
|
||||||
|
|
||||||
queryset = users.User.objects.exclude(groups__listright__critical=True).distinct()
|
queryset = users.User.objects.exclude(groups__listright__critical=True).distinct()
|
||||||
serializer_class = serializers.BasicUserSerializer
|
serializer_class = serializers.BasicUserSerializer
|
||||||
|
|
||||||
|
|
||||||
class CriticalUserViewSet(viewsets.ReadOnlyModelViewSet):
|
class CriticalUserViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes infos of `users.models.Users`without specific rights objects."""
|
"""Exposes infos of `users.models.Users`without specific rights objects."""
|
||||||
|
|
||||||
queryset = users.User.objects.filter(groups__listright__critical=True).distinct()
|
queryset = users.User.objects.filter(groups__listright__critical=True).distinct()
|
||||||
serializer_class = serializers.BasicUserSerializer
|
serializer_class = serializers.BasicUserSerializer
|
||||||
|
|
||||||
|
@ -474,6 +534,7 @@ class CriticalUserViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class ClubViewSet(viewsets.ReadOnlyModelViewSet):
|
class ClubViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `users.models.Club` objects.
|
"""Exposes list and details of `users.models.Club` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = users.Club.objects.all()
|
queryset = users.Club.objects.all()
|
||||||
serializer_class = serializers.ClubSerializer
|
serializer_class = serializers.ClubSerializer
|
||||||
|
|
||||||
|
@ -481,6 +542,7 @@ class ClubViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class AdherentViewSet(viewsets.ReadOnlyModelViewSet):
|
class AdherentViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `users.models.Adherent` objects.
|
"""Exposes list and details of `users.models.Adherent` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = users.Adherent.objects.all()
|
queryset = users.Adherent.objects.all()
|
||||||
serializer_class = serializers.AdherentSerializer
|
serializer_class = serializers.AdherentSerializer
|
||||||
|
|
||||||
|
@ -488,6 +550,7 @@ class AdherentViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class ServiceUserViewSet(viewsets.ReadOnlyModelViewSet):
|
class ServiceUserViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `users.models.ServiceUser` objects.
|
"""Exposes list and details of `users.models.ServiceUser` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = users.ServiceUser.objects.all()
|
queryset = users.ServiceUser.objects.all()
|
||||||
serializer_class = serializers.ServiceUserSerializer
|
serializer_class = serializers.ServiceUserSerializer
|
||||||
|
|
||||||
|
@ -495,6 +558,7 @@ class ServiceUserViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class SchoolViewSet(viewsets.ReadOnlyModelViewSet):
|
class SchoolViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `users.models.School` objects.
|
"""Exposes list and details of `users.models.School` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = users.School.objects.all()
|
queryset = users.School.objects.all()
|
||||||
serializer_class = serializers.SchoolSerializer
|
serializer_class = serializers.SchoolSerializer
|
||||||
|
|
||||||
|
@ -502,6 +566,7 @@ class SchoolViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class ListRightViewSet(viewsets.ReadOnlyModelViewSet):
|
class ListRightViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `users.models.ListRight` objects.
|
"""Exposes list and details of `users.models.ListRight` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = users.ListRight.objects.all()
|
queryset = users.ListRight.objects.all()
|
||||||
serializer_class = serializers.ListRightSerializer
|
serializer_class = serializers.ListRightSerializer
|
||||||
|
|
||||||
|
@ -509,6 +574,7 @@ class ListRightViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class ShellViewSet(viewsets.ReadOnlyModelViewSet):
|
class ShellViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `users.models.ListShell` objects.
|
"""Exposes list and details of `users.models.ListShell` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = users.ListShell.objects.all()
|
queryset = users.ListShell.objects.all()
|
||||||
serializer_class = serializers.ShellSerializer
|
serializer_class = serializers.ShellSerializer
|
||||||
|
|
||||||
|
@ -516,6 +582,7 @@ class ShellViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class BanViewSet(viewsets.ReadOnlyModelViewSet):
|
class BanViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `users.models.Ban` objects.
|
"""Exposes list and details of `users.models.Ban` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = users.Ban.objects.all()
|
queryset = users.Ban.objects.all()
|
||||||
serializer_class = serializers.BanSerializer
|
serializer_class = serializers.BanSerializer
|
||||||
|
|
||||||
|
@ -523,6 +590,7 @@ class BanViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class WhitelistViewSet(viewsets.ReadOnlyModelViewSet):
|
class WhitelistViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `users.models.Whitelist` objects.
|
"""Exposes list and details of `users.models.Whitelist` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = users.Whitelist.objects.all()
|
queryset = users.Whitelist.objects.all()
|
||||||
serializer_class = serializers.WhitelistSerializer
|
serializer_class = serializers.WhitelistSerializer
|
||||||
|
|
||||||
|
@ -530,14 +598,13 @@ class WhitelistViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class EMailAddressViewSet(viewsets.ReadOnlyModelViewSet):
|
class EMailAddressViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `users.models.EMailAddress` objects.
|
"""Exposes list and details of `users.models.EMailAddress` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
serializer_class = serializers.EMailAddressSerializer
|
serializer_class = serializers.EMailAddressSerializer
|
||||||
queryset = users.EMailAddress.objects.none()
|
queryset = users.EMailAddress.objects.none()
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
if preferences.OptionalUser.get_cached_value(
|
if preferences.OptionalUser.get_cached_value("local_email_accounts_enabled"):
|
||||||
'local_email_accounts_enabled'):
|
return users.EMailAddress.objects.filter(user__local_email_enabled=True)
|
||||||
return (users.EMailAddress.objects
|
|
||||||
.filter(user__local_email_enabled=True))
|
|
||||||
else:
|
else:
|
||||||
return users.EMailAddress.objects.none()
|
return users.EMailAddress.objects.none()
|
||||||
|
|
||||||
|
@ -548,34 +615,47 @@ class EMailAddressViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
class ServiceRegenViewSet(viewsets.ModelViewSet):
|
class ServiceRegenViewSet(viewsets.ModelViewSet):
|
||||||
"""Exposes list and details of the services to regen
|
"""Exposes list and details of the services to regen
|
||||||
"""
|
"""
|
||||||
|
|
||||||
serializer_class = serializers.ServiceRegenSerializer
|
serializer_class = serializers.ServiceRegenSerializer
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
queryset = machines.Service_link.objects.select_related(
|
queryset = machines.Service_link.objects.select_related(
|
||||||
'server__domain'
|
"server__domain"
|
||||||
).select_related(
|
).select_related("service")
|
||||||
'service'
|
if "hostname" in self.request.GET:
|
||||||
)
|
hostname = self.request.GET["hostname"]
|
||||||
if 'hostname' in self.request.GET:
|
|
||||||
hostname = self.request.GET['hostname']
|
|
||||||
queryset = queryset.filter(server__domain__name__iexact=hostname)
|
queryset = queryset.filter(server__domain__name__iexact=hostname)
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
# Config des switches
|
# Config des switches
|
||||||
|
|
||||||
|
|
||||||
class SwitchPortView(generics.ListAPIView):
|
class SwitchPortView(generics.ListAPIView):
|
||||||
"""Output each port of a switch, to be serialized with
|
"""Output each port of a switch, to be serialized with
|
||||||
additionnal informations (profiles etc)
|
additionnal informations (profiles etc)
|
||||||
"""
|
"""
|
||||||
queryset = topologie.Switch.objects.all().select_related("switchbay").select_related("model__constructor").prefetch_related("ports__custom_profile__vlan_tagged").prefetch_related("ports__custom_profile__vlan_untagged").prefetch_related("ports__machine_interface__domain__extension").prefetch_related("ports__room")
|
|
||||||
|
queryset = (
|
||||||
|
topologie.Switch.objects.all()
|
||||||
|
.select_related("switchbay")
|
||||||
|
.select_related("model__constructor")
|
||||||
|
.prefetch_related("ports__custom_profile__vlan_tagged")
|
||||||
|
.prefetch_related("ports__custom_profile__vlan_untagged")
|
||||||
|
.prefetch_related("ports__machine_interface__domain__extension")
|
||||||
|
.prefetch_related("ports__room")
|
||||||
|
)
|
||||||
|
|
||||||
serializer_class = serializers.SwitchPortSerializer
|
serializer_class = serializers.SwitchPortSerializer
|
||||||
|
|
||||||
|
|
||||||
# Rappel fin adhésion
|
# Rappel fin adhésion
|
||||||
|
|
||||||
|
|
||||||
class ReminderView(generics.ListAPIView):
|
class ReminderView(generics.ListAPIView):
|
||||||
"""Output for users to remind an end of their subscription.
|
"""Output for users to remind an end of their subscription.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = preferences.Reminder.objects.all()
|
queryset = preferences.Reminder.objects.all()
|
||||||
serializer_class = serializers.ReminderSerializer
|
serializer_class = serializers.ReminderSerializer
|
||||||
|
|
||||||
|
@ -583,7 +663,8 @@ class ReminderView(generics.ListAPIView):
|
||||||
class RoleView(generics.ListAPIView):
|
class RoleView(generics.ListAPIView):
|
||||||
"""Output of roles for each server
|
"""Output of roles for each server
|
||||||
"""
|
"""
|
||||||
queryset = machines.Role.objects.all().prefetch_related('servers')
|
|
||||||
|
queryset = machines.Role.objects.all().prefetch_related("servers")
|
||||||
serializer_class = serializers.RoleSerializer
|
serializer_class = serializers.RoleSerializer
|
||||||
|
|
||||||
|
|
||||||
|
@ -593,13 +674,12 @@ class RoleView(generics.ListAPIView):
|
||||||
class LocalEmailUsersView(generics.ListAPIView):
|
class LocalEmailUsersView(generics.ListAPIView):
|
||||||
"""Exposes all the aliases of the users that activated the internal address
|
"""Exposes all the aliases of the users that activated the internal address
|
||||||
"""
|
"""
|
||||||
|
|
||||||
serializer_class = serializers.LocalEmailUsersSerializer
|
serializer_class = serializers.LocalEmailUsersSerializer
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
if preferences.OptionalUser.get_cached_value(
|
if preferences.OptionalUser.get_cached_value("local_email_accounts_enabled"):
|
||||||
'local_email_accounts_enabled'):
|
return users.User.objects.filter(local_email_enabled=True)
|
||||||
return (users.User.objects
|
|
||||||
.filter(local_email_enabled=True))
|
|
||||||
else:
|
else:
|
||||||
return users.User.objects.none()
|
return users.User.objects.none()
|
||||||
|
|
||||||
|
@ -611,6 +691,7 @@ class HostMacIpView(generics.ListAPIView):
|
||||||
"""Exposes the associations between hostname, mac address and IPv4 in
|
"""Exposes the associations between hostname, mac address and IPv4 in
|
||||||
order to build the DHCP lease files.
|
order to build the DHCP lease files.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
serializer_class = serializers.HostMacIpSerializer
|
serializer_class = serializers.HostMacIpSerializer
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
|
@ -619,6 +700,7 @@ class HostMacIpView(generics.ListAPIView):
|
||||||
|
|
||||||
# Firewall
|
# Firewall
|
||||||
|
|
||||||
|
|
||||||
class SubnetPortsOpenView(generics.ListAPIView):
|
class SubnetPortsOpenView(generics.ListAPIView):
|
||||||
queryset = machines.IpType.objects.all()
|
queryset = machines.IpType.objects.all()
|
||||||
serializer_class = serializers.SubnetPortsOpenSerializer
|
serializer_class = serializers.SubnetPortsOpenSerializer
|
||||||
|
@ -636,14 +718,19 @@ class DNSZonesView(generics.ListAPIView):
|
||||||
"""Exposes the detailed information about each extension (hostnames,
|
"""Exposes the detailed information about each extension (hostnames,
|
||||||
IPs, DNS records, etc.) in order to build the DNS zone files.
|
IPs, DNS records, etc.) in order to build the DNS zone files.
|
||||||
"""
|
"""
|
||||||
queryset = (machines.Extension.objects
|
|
||||||
.prefetch_related('soa')
|
queryset = (
|
||||||
.prefetch_related('ns_set').prefetch_related('ns_set__ns')
|
machines.Extension.objects.prefetch_related("soa")
|
||||||
.prefetch_related('origin')
|
.prefetch_related("ns_set")
|
||||||
.prefetch_related('mx_set').prefetch_related('mx_set__name')
|
.prefetch_related("ns_set__ns")
|
||||||
.prefetch_related('txt_set')
|
.prefetch_related("origin")
|
||||||
.prefetch_related('srv_set').prefetch_related('srv_set__target')
|
.prefetch_related("mx_set")
|
||||||
.all())
|
.prefetch_related("mx_set__name")
|
||||||
|
.prefetch_related("txt_set")
|
||||||
|
.prefetch_related("srv_set")
|
||||||
|
.prefetch_related("srv_set__target")
|
||||||
|
.all()
|
||||||
|
)
|
||||||
serializer_class = serializers.DNSZonesSerializer
|
serializer_class = serializers.DNSZonesSerializer
|
||||||
|
|
||||||
|
|
||||||
|
@ -651,7 +738,8 @@ class DNSReverseZonesView(generics.ListAPIView):
|
||||||
"""Exposes the detailed information about each extension (hostnames,
|
"""Exposes the detailed information about each extension (hostnames,
|
||||||
IPs, DNS records, etc.) in order to build the DNS zone files.
|
IPs, DNS records, etc.) in order to build the DNS zone files.
|
||||||
"""
|
"""
|
||||||
queryset = (machines.IpType.objects.all())
|
|
||||||
|
queryset = machines.IpType.objects.all()
|
||||||
serializer_class = serializers.DNSReverseZonesSerializer
|
serializer_class = serializers.DNSReverseZonesSerializer
|
||||||
|
|
||||||
|
|
||||||
|
@ -662,13 +750,16 @@ class StandardMailingView(views.APIView):
|
||||||
"""Exposes list and details of standard mailings (name and members) in
|
"""Exposes list and details of standard mailings (name and members) in
|
||||||
order to building the corresponding mailing lists.
|
order to building the corresponding mailing lists.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
pagination_class = PageSizedPagination
|
pagination_class = PageSizedPagination
|
||||||
permission_classes = (ACLPermission,)
|
permission_classes = (ACLPermission,)
|
||||||
perms_map = {'GET': [users.User.can_view_all]}
|
perms_map = {"GET": [users.User.can_view_all]}
|
||||||
|
|
||||||
def get(self, request, format=None):
|
def get(self, request, format=None):
|
||||||
adherents_data = serializers.MailingMemberSerializer(all_has_access(), many=True).data
|
adherents_data = serializers.MailingMemberSerializer(
|
||||||
data = [{'name': 'adherents', 'members': adherents_data}]
|
all_has_access(), many=True
|
||||||
|
).data
|
||||||
|
data = [{"name": "adherents", "members": adherents_data}]
|
||||||
paginator = self.pagination_class()
|
paginator = self.pagination_class()
|
||||||
paginator.paginate_queryset(data, request)
|
paginator.paginate_queryset(data, request)
|
||||||
return paginator.get_paginated_response(data)
|
return paginator.get_paginated_response(data)
|
||||||
|
@ -678,6 +769,7 @@ class ClubMailingView(generics.ListAPIView):
|
||||||
"""Exposes list and details of club mailings (name, members and admins) in
|
"""Exposes list and details of club mailings (name, members and admins) in
|
||||||
order to build the corresponding mailing lists.
|
order to build the corresponding mailing lists.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = users.Club.objects.all()
|
queryset = users.Club.objects.all()
|
||||||
serializer_class = serializers.MailingSerializer
|
serializer_class = serializers.MailingSerializer
|
||||||
|
|
||||||
|
@ -696,12 +788,10 @@ class ObtainExpiringAuthToken(ObtainAuthToken):
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
serializer = self.serializer_class(data=request.data)
|
serializer = self.serializer_class(data=request.data)
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
user = serializer.validated_data['user']
|
user = serializer.validated_data["user"]
|
||||||
token, created = Token.objects.get_or_create(user=user)
|
token, created = Token.objects.get_or_create(user=user)
|
||||||
|
|
||||||
token_duration = datetime.timedelta(
|
token_duration = datetime.timedelta(seconds=settings.API_TOKEN_DURATION)
|
||||||
seconds=settings.API_TOKEN_DURATION
|
|
||||||
)
|
|
||||||
utc_now = datetime.datetime.now(datetime.timezone.utc)
|
utc_now = datetime.datetime.now(datetime.timezone.utc)
|
||||||
if not created and token.created < utc_now - token_duration:
|
if not created and token.created < utc_now - token_duration:
|
||||||
token.delete()
|
token.delete()
|
||||||
|
@ -709,7 +799,6 @@ class ObtainExpiringAuthToken(ObtainAuthToken):
|
||||||
token.created = datetime.datetime.utcnow()
|
token.created = datetime.datetime.utcnow()
|
||||||
token.save()
|
token.save()
|
||||||
|
|
||||||
return Response({
|
return Response(
|
||||||
'token': token.key,
|
{"token": token.key, "expiration": token.created + token_duration}
|
||||||
'expiration': token.created + token_duration
|
)
|
||||||
})
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ texlive-fonts-recommended
|
||||||
python3-djangorestframework
|
python3-djangorestframework
|
||||||
python3-django-reversion
|
python3-django-reversion
|
||||||
python3-pip
|
python3-pip
|
||||||
|
python3-pil
|
||||||
libsasl2-dev libldap2-dev
|
libsasl2-dev libldap2-dev
|
||||||
libssl-dev
|
libssl-dev
|
||||||
python3-crypto
|
python3-crypto
|
||||||
|
@ -18,3 +19,4 @@ fonts-font-awesome
|
||||||
graphviz
|
graphviz
|
||||||
git
|
git
|
||||||
gettext
|
gettext
|
||||||
|
python3-django-ldapdb
|
||||||
|
|
23
apt_requirements_radius.txt
Normal file
23
apt_requirements_radius.txt
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
python-django
|
||||||
|
python-dateutil
|
||||||
|
texlive-latex-base
|
||||||
|
texlive-fonts-recommended
|
||||||
|
python-djangorestframework
|
||||||
|
python-django-reversion
|
||||||
|
python-pip
|
||||||
|
libsasl2-dev libldap2-dev
|
||||||
|
libssl-dev
|
||||||
|
python-crypto
|
||||||
|
python-git
|
||||||
|
javascript-common
|
||||||
|
libjs-jquery
|
||||||
|
libjs-jquery-ui
|
||||||
|
libjs-jquery-timepicker
|
||||||
|
libjs-bootstrap
|
||||||
|
fonts-font-awesome
|
||||||
|
graphviz
|
||||||
|
git
|
||||||
|
gettext
|
||||||
|
freeradius-common
|
||||||
|
freeradius-python2
|
||||||
|
python-mysqldb
|
|
@ -4,7 +4,7 @@
|
||||||
# quelques clics.
|
# quelques clics.
|
||||||
#
|
#
|
||||||
# Copyright © 2017 Gabriel Détraz
|
# Copyright © 2017 Gabriel Détraz
|
||||||
# Copyright © 2017 Goulven Kermarec
|
# Copyright © 2017 Lara Kermarec
|
||||||
# Copyright © 2017 Augustin Lemesle
|
# Copyright © 2017 Augustin Lemesle
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
# quelques clics.
|
# quelques clics.
|
||||||
#
|
#
|
||||||
# Copyright © 2017 Gabriel Détraz
|
# Copyright © 2017 Gabriel Détraz
|
||||||
# Copyright © 2017 Goulven Kermarec
|
# Copyright © 2017 Lara Kermarec
|
||||||
# Copyright © 2017 Augustin Lemesle
|
# Copyright © 2017 Augustin Lemesle
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -38,9 +38,12 @@ def can_view(user):
|
||||||
A couple (allowed, msg) where allowed is a boolean which is True if
|
A couple (allowed, msg) where allowed is a boolean which is True if
|
||||||
viewing is granted and msg is a message (can be None).
|
viewing is granted and msg is a message (can be None).
|
||||||
"""
|
"""
|
||||||
can = user.has_module_perms('cotisations')
|
can = user.has_module_perms("cotisations")
|
||||||
if can:
|
if can:
|
||||||
return can, None
|
return can, None, ("cotisations",)
|
||||||
else:
|
else:
|
||||||
return can, _("You don't have the right to view this application.")
|
return (
|
||||||
|
can,
|
||||||
|
_("You don't have the right to view this application."),
|
||||||
|
("cotisations",),
|
||||||
|
)
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
# quelques clics.
|
# quelques clics.
|
||||||
#
|
#
|
||||||
# Copyright © 2017 Gabriel Détraz
|
# Copyright © 2017 Gabriel Détraz
|
||||||
# Copyright © 2017 Goulven Kermarec
|
# Copyright © 2017 Lara Kermarec
|
||||||
# Copyright © 2017 Augustin Lemesle
|
# Copyright © 2017 Augustin Lemesle
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -35,42 +35,50 @@ from .models import CustomInvoice, CostEstimate
|
||||||
|
|
||||||
class FactureAdmin(VersionAdmin):
|
class FactureAdmin(VersionAdmin):
|
||||||
"""Class admin d'une facture, tous les champs"""
|
"""Class admin d'une facture, tous les champs"""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class CostEstimateAdmin(VersionAdmin):
|
class CostEstimateAdmin(VersionAdmin):
|
||||||
"""Admin class for cost estimates."""
|
"""Admin class for cost estimates."""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class CustomInvoiceAdmin(VersionAdmin):
|
class CustomInvoiceAdmin(VersionAdmin):
|
||||||
"""Admin class for custom invoices."""
|
"""Admin class for custom invoices."""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class VenteAdmin(VersionAdmin):
|
class VenteAdmin(VersionAdmin):
|
||||||
"""Class admin d'une vente, tous les champs (facture related)"""
|
"""Class admin d'une vente, tous les champs (facture related)"""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ArticleAdmin(VersionAdmin):
|
class ArticleAdmin(VersionAdmin):
|
||||||
"""Class admin d'un article en vente"""
|
"""Class admin d'un article en vente"""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class BanqueAdmin(VersionAdmin):
|
class BanqueAdmin(VersionAdmin):
|
||||||
"""Class admin de la liste des banques (facture related)"""
|
"""Class admin de la liste des banques (facture related)"""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class PaiementAdmin(VersionAdmin):
|
class PaiementAdmin(VersionAdmin):
|
||||||
"""Class admin d'un moyen de paiement (facture related"""
|
"""Class admin d'un moyen de paiement (facture related"""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class CotisationAdmin(VersionAdmin):
|
class CotisationAdmin(VersionAdmin):
|
||||||
"""Class admin d'une cotisation (date de debut et de fin),
|
"""Class admin d'une cotisation (date de debut et de fin),
|
||||||
Vente related"""
|
Vente related"""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# quelques clics.
|
# quelques clics.
|
||||||
#
|
#
|
||||||
# Copyright © 2017 Gabriel Détraz
|
# Copyright © 2017 Gabriel Détraz
|
||||||
# Copyright © 2017 Goulven Kermarec
|
# Copyright © 2017 Lara Kermarec
|
||||||
# Copyright © 2017 Augustin Lemesle
|
# Copyright © 2017 Augustin Lemesle
|
||||||
# Copyright © 2018 Hugo Levy-Falk
|
# Copyright © 2018 Hugo Levy-Falk
|
||||||
#
|
#
|
||||||
|
@ -47,8 +47,13 @@ from django.shortcuts import get_object_or_404
|
||||||
from re2o.field_permissions import FieldPermissionFormMixin
|
from re2o.field_permissions import FieldPermissionFormMixin
|
||||||
from re2o.mixins import FormRevMixin
|
from re2o.mixins import FormRevMixin
|
||||||
from .models import (
|
from .models import (
|
||||||
Article, Paiement, Facture, Banque,
|
Article,
|
||||||
CustomInvoice, Vente, CostEstimate,
|
Paiement,
|
||||||
|
Facture,
|
||||||
|
Banque,
|
||||||
|
CustomInvoice,
|
||||||
|
Vente,
|
||||||
|
CostEstimate,
|
||||||
)
|
)
|
||||||
from .payment_methods import balance
|
from .payment_methods import balance
|
||||||
|
|
||||||
|
@ -59,31 +64,27 @@ class FactureForm(FieldPermissionFormMixin, FormRevMixin, ModelForm):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, *args, creation=False, **kwargs):
|
def __init__(self, *args, creation=False, **kwargs):
|
||||||
user = kwargs['user']
|
user = kwargs["user"]
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
super(FactureForm, self).__init__(*args, prefix=prefix, **kwargs)
|
super(FactureForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
self.fields['paiement'].empty_label = \
|
self.fields["paiement"].empty_label = _("Select a payment method")
|
||||||
_("Select a payment method")
|
self.fields["paiement"].queryset = Paiement.find_allowed_payments(user)
|
||||||
self.fields['paiement'].queryset = Paiement.find_allowed_payments(user)
|
|
||||||
if not creation:
|
if not creation:
|
||||||
self.fields['user'].label = _("Member")
|
self.fields["user"].label = _("Member")
|
||||||
self.fields['user'].empty_label = \
|
self.fields["user"].empty_label = _("Select the proprietary member")
|
||||||
_("Select the proprietary member")
|
self.fields["valid"].label = _("Validated invoice")
|
||||||
self.fields['valid'].label = _("Validated invoice")
|
|
||||||
else:
|
else:
|
||||||
self.fields = {'paiement': self.fields['paiement']}
|
self.fields = {"paiement": self.fields["paiement"]}
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Facture
|
model = Facture
|
||||||
fields = '__all__'
|
fields = "__all__"
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
cleaned_data = super(FactureForm, self).clean()
|
cleaned_data = super(FactureForm, self).clean()
|
||||||
paiement = cleaned_data.get('paiement')
|
paiement = cleaned_data.get("paiement")
|
||||||
if not paiement:
|
if not paiement:
|
||||||
raise forms.ValidationError(
|
raise forms.ValidationError(_("A payment method must be specified."))
|
||||||
_("A payment method must be specified.")
|
|
||||||
)
|
|
||||||
return cleaned_data
|
return cleaned_data
|
||||||
|
|
||||||
|
|
||||||
|
@ -92,32 +93,30 @@ class SelectArticleForm(FormRevMixin, Form):
|
||||||
Form used to select an article during the creation of an invoice for a
|
Form used to select an article during the creation of an invoice for a
|
||||||
member.
|
member.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
article = forms.ModelChoiceField(
|
article = forms.ModelChoiceField(
|
||||||
queryset=Article.objects.none(),
|
queryset=Article.objects.none(), label=_("Article"), required=True
|
||||||
label=_("Article"),
|
|
||||||
required=True
|
|
||||||
)
|
)
|
||||||
quantity = forms.IntegerField(
|
quantity = forms.IntegerField(
|
||||||
label=_("Quantity"),
|
label=_("Quantity"), validators=[MinValueValidator(1)], required=True
|
||||||
validators=[MinValueValidator(1)],
|
|
||||||
required=True
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
user = kwargs.pop('user')
|
user = kwargs.pop("user")
|
||||||
target_user = kwargs.pop('target_user', None)
|
target_user = kwargs.pop("target_user", None)
|
||||||
super(SelectArticleForm, self).__init__(*args, **kwargs)
|
super(SelectArticleForm, self).__init__(*args, **kwargs)
|
||||||
self.fields['article'].queryset = Article.find_allowed_articles(
|
self.fields["article"].queryset = Article.find_allowed_articles(
|
||||||
user, target_user)
|
user, target_user
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class DiscountForm(Form):
|
class DiscountForm(Form):
|
||||||
"""
|
"""
|
||||||
Form used in oder to create a discount on an invoice.
|
Form used in oder to create a discount on an invoice.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
is_relative = forms.BooleanField(
|
is_relative = forms.BooleanField(
|
||||||
label=_("Discount is on percentage."),
|
label=_("Discount is in percentage."), required=False
|
||||||
required=False,
|
|
||||||
)
|
)
|
||||||
discount = forms.DecimalField(
|
discount = forms.DecimalField(
|
||||||
label=_("Discount"),
|
label=_("Discount"),
|
||||||
|
@ -130,53 +129,51 @@ class DiscountForm(Form):
|
||||||
|
|
||||||
def apply_to_invoice(self, invoice):
|
def apply_to_invoice(self, invoice):
|
||||||
invoice_price = invoice.prix_total()
|
invoice_price = invoice.prix_total()
|
||||||
discount = self.cleaned_data['discount']
|
discount = self.cleaned_data["discount"]
|
||||||
is_relative = self.cleaned_data['is_relative']
|
is_relative = self.cleaned_data["is_relative"]
|
||||||
if is_relative:
|
if is_relative:
|
||||||
amount = discount/100 * invoice_price
|
amount = discount / 100 * invoice_price
|
||||||
else:
|
else:
|
||||||
amount = discount
|
amount = discount
|
||||||
if amount:
|
if amount:
|
||||||
name = _("{}% discount") if is_relative else _("{}€ discount")
|
name = _("{}% discount") if is_relative else _("{} € discount")
|
||||||
name = name.format(discount)
|
name = name.format(discount)
|
||||||
Vente.objects.create(
|
Vente.objects.create(facture=invoice, name=name, prix=-amount, number=1)
|
||||||
facture=invoice,
|
|
||||||
name=name,
|
|
||||||
prix=-amount,
|
|
||||||
number=1
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class CustomInvoiceForm(FormRevMixin, ModelForm):
|
class CustomInvoiceForm(FormRevMixin, ModelForm):
|
||||||
"""
|
"""
|
||||||
Form used to create a custom invoice.
|
Form used to create a custom invoice.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = CustomInvoice
|
model = CustomInvoice
|
||||||
fields = '__all__'
|
fields = "__all__"
|
||||||
|
|
||||||
|
|
||||||
class CostEstimateForm(FormRevMixin, ModelForm):
|
class CostEstimateForm(FormRevMixin, ModelForm):
|
||||||
"""
|
"""
|
||||||
Form used to create a cost estimate.
|
Form used to create a cost estimate.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = CostEstimate
|
model = CostEstimate
|
||||||
exclude = ['paid', 'final_invoice']
|
exclude = ["paid", "final_invoice"]
|
||||||
|
|
||||||
|
|
||||||
class ArticleForm(FormRevMixin, ModelForm):
|
class ArticleForm(FormRevMixin, ModelForm):
|
||||||
"""
|
"""
|
||||||
Form used to create an article.
|
Form used to create an article.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Article
|
model = Article
|
||||||
fields = '__all__'
|
fields = "__all__"
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
super(ArticleForm, self).__init__(*args, prefix=prefix, **kwargs)
|
super(ArticleForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
self.fields['name'].label = _("Article name")
|
self.fields["name"].label = _("Article name")
|
||||||
|
|
||||||
|
|
||||||
class DelArticleForm(FormRevMixin, Form):
|
class DelArticleForm(FormRevMixin, Form):
|
||||||
|
@ -184,19 +181,20 @@ class DelArticleForm(FormRevMixin, Form):
|
||||||
Form used to delete one or more of the currently available articles.
|
Form used to delete one or more of the currently available articles.
|
||||||
The user must choose the one to delete by checking the boxes.
|
The user must choose the one to delete by checking the boxes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
articles = forms.ModelMultipleChoiceField(
|
articles = forms.ModelMultipleChoiceField(
|
||||||
queryset=Article.objects.none(),
|
queryset=Article.objects.none(),
|
||||||
label=_("Available articles"),
|
label=_("Current articles"),
|
||||||
widget=forms.CheckboxSelectMultiple
|
widget=forms.CheckboxSelectMultiple,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
instances = kwargs.pop('instances', None)
|
instances = kwargs.pop("instances", None)
|
||||||
super(DelArticleForm, self).__init__(*args, **kwargs)
|
super(DelArticleForm, self).__init__(*args, **kwargs)
|
||||||
if instances:
|
if instances:
|
||||||
self.fields['articles'].queryset = instances
|
self.fields["articles"].queryset = instances
|
||||||
else:
|
else:
|
||||||
self.fields['articles'].queryset = Article.objects.all()
|
self.fields["articles"].queryset = Article.objects.all()
|
||||||
|
|
||||||
|
|
||||||
# TODO : change Paiement to Payment
|
# TODO : change Paiement to Payment
|
||||||
|
@ -206,15 +204,16 @@ class PaiementForm(FormRevMixin, ModelForm):
|
||||||
The 'cheque' type is used to associate a specific behaviour requiring
|
The 'cheque' type is used to associate a specific behaviour requiring
|
||||||
a cheque number and a bank.
|
a cheque number and a bank.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Paiement
|
model = Paiement
|
||||||
# TODO : change moyen to method and type_paiement to payment_type
|
# TODO : change moyen to method and type_paiement to payment_type
|
||||||
fields = ['moyen', 'available_for_everyone']
|
fields = ["moyen", "available_for_everyone"]
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
super(PaiementForm, self).__init__(*args, prefix=prefix, **kwargs)
|
super(PaiementForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
self.fields['moyen'].label = _("Payment method name")
|
self.fields["moyen"].label = _("Payment method name")
|
||||||
|
|
||||||
|
|
||||||
# TODO : change paiement to payment
|
# TODO : change paiement to payment
|
||||||
|
@ -223,20 +222,21 @@ class DelPaiementForm(FormRevMixin, Form):
|
||||||
Form used to delete one or more payment methods.
|
Form used to delete one or more payment methods.
|
||||||
The user must choose the one to delete by checking the boxes.
|
The user must choose the one to delete by checking the boxes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# TODO : change paiement to payment
|
# TODO : change paiement to payment
|
||||||
paiements = forms.ModelMultipleChoiceField(
|
paiements = forms.ModelMultipleChoiceField(
|
||||||
queryset=Paiement.objects.none(),
|
queryset=Paiement.objects.none(),
|
||||||
label=_("Available payment methods"),
|
label=_("Current payment methods"),
|
||||||
widget=forms.CheckboxSelectMultiple
|
widget=forms.CheckboxSelectMultiple,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
instances = kwargs.pop('instances', None)
|
instances = kwargs.pop("instances", None)
|
||||||
super(DelPaiementForm, self).__init__(*args, **kwargs)
|
super(DelPaiementForm, self).__init__(*args, **kwargs)
|
||||||
if instances:
|
if instances:
|
||||||
self.fields['paiements'].queryset = instances
|
self.fields["paiements"].queryset = instances
|
||||||
else:
|
else:
|
||||||
self.fields['paiements'].queryset = Paiement.objects.all()
|
self.fields["paiements"].queryset = Paiement.objects.all()
|
||||||
|
|
||||||
|
|
||||||
# TODO : change banque to bank
|
# TODO : change banque to bank
|
||||||
|
@ -244,15 +244,16 @@ class BanqueForm(FormRevMixin, ModelForm):
|
||||||
"""
|
"""
|
||||||
Form used to create a bank.
|
Form used to create a bank.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
# TODO : change banque to bank
|
# TODO : change banque to bank
|
||||||
model = Banque
|
model = Banque
|
||||||
fields = ['name']
|
fields = ["name"]
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
super(BanqueForm, self).__init__(*args, prefix=prefix, **kwargs)
|
super(BanqueForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
self.fields['name'].label = _("Bank name")
|
self.fields["name"].label = _("Bank name")
|
||||||
|
|
||||||
|
|
||||||
# TODO : change banque to bank
|
# TODO : change banque to bank
|
||||||
|
@ -261,20 +262,21 @@ class DelBanqueForm(FormRevMixin, Form):
|
||||||
Form used to delete one or more banks.
|
Form used to delete one or more banks.
|
||||||
The use must choose the one to delete by checking the boxes.
|
The use must choose the one to delete by checking the boxes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# TODO : change banque to bank
|
# TODO : change banque to bank
|
||||||
banques = forms.ModelMultipleChoiceField(
|
banques = forms.ModelMultipleChoiceField(
|
||||||
queryset=Banque.objects.none(),
|
queryset=Banque.objects.none(),
|
||||||
label=_("Available banks"),
|
label=_("Current banks"),
|
||||||
widget=forms.CheckboxSelectMultiple
|
widget=forms.CheckboxSelectMultiple,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
instances = kwargs.pop('instances', None)
|
instances = kwargs.pop("instances", None)
|
||||||
super(DelBanqueForm, self).__init__(*args, **kwargs)
|
super(DelBanqueForm, self).__init__(*args, **kwargs)
|
||||||
if instances:
|
if instances:
|
||||||
self.fields['banques'].queryset = instances
|
self.fields["banques"].queryset = instances
|
||||||
else:
|
else:
|
||||||
self.fields['banques'].queryset = Banque.objects.all()
|
self.fields["banques"].queryset = Banque.objects.all()
|
||||||
|
|
||||||
|
|
||||||
# TODO : Better name and docstring
|
# TODO : Better name and docstring
|
||||||
|
@ -282,37 +284,36 @@ class RechargeForm(FormRevMixin, Form):
|
||||||
"""
|
"""
|
||||||
Form used to refill a user's balance
|
Form used to refill a user's balance
|
||||||
"""
|
"""
|
||||||
value = forms.DecimalField(
|
|
||||||
label=_("Amount"),
|
value = forms.DecimalField(label=_("Amount"), decimal_places=2)
|
||||||
min_value=0.01,
|
|
||||||
validators=[]
|
|
||||||
)
|
|
||||||
payment = forms.ModelChoiceField(
|
payment = forms.ModelChoiceField(
|
||||||
queryset=Paiement.objects.none(),
|
queryset=Paiement.objects.none(), label=_("Payment method")
|
||||||
label=_("Payment method")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, user=None, user_source=None, **kwargs):
|
def __init__(self, *args, user=None, user_source=None, **kwargs):
|
||||||
self.user = user
|
self.user = user
|
||||||
super(RechargeForm, self).__init__(*args, **kwargs)
|
super(RechargeForm, self).__init__(*args, **kwargs)
|
||||||
self.fields['payment'].empty_label = \
|
self.fields["payment"].empty_label = _("Select a payment method")
|
||||||
_("Select a payment method")
|
self.fields["payment"].queryset = Paiement.find_allowed_payments(
|
||||||
self.fields['payment'].queryset = Paiement.find_allowed_payments(
|
user_source
|
||||||
user_source).exclude(is_balance=True)
|
).exclude(is_balance=True)
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
"""
|
"""
|
||||||
Returns a cleaned value from the received form by validating
|
Returns a cleaned value from the received form by validating
|
||||||
the value is well inside the possible limits
|
the value is well inside the possible limits
|
||||||
"""
|
"""
|
||||||
value = self.cleaned_data['value']
|
value = self.cleaned_data["value"]
|
||||||
balance_method = get_object_or_404(balance.PaymentMethod)
|
balance_method = get_object_or_404(balance.PaymentMethod)
|
||||||
if balance_method.maximum_balance is not None and \
|
if (
|
||||||
value + self.user.solde > balance_method.maximum_balance:
|
balance_method.maximum_balance is not None
|
||||||
|
and value + self.user.solde > balance_method.maximum_balance
|
||||||
|
):
|
||||||
raise forms.ValidationError(
|
raise forms.ValidationError(
|
||||||
_("Requested amount is too high. Your balance can't exceed"
|
_(
|
||||||
" %(max_online_balance)s €.") % {
|
"Requested amount is too high. Your balance can't exceed"
|
||||||
'max_online_balance': balance_method.maximum_balance
|
" %(max_online_balance)s €."
|
||||||
}
|
)
|
||||||
|
% {"max_online_balance": balance_method.maximum_balance}
|
||||||
)
|
)
|
||||||
return self.cleaned_data
|
return self.cleaned_data
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -3,7 +3,7 @@
|
||||||
# quelques clics.
|
# quelques clics.
|
||||||
#
|
#
|
||||||
# Copyright © 2017 Gabriel Détraz
|
# Copyright © 2017 Gabriel Détraz
|
||||||
# Copyright © 2017 Goulven Kermarec
|
# Copyright © 2017 Lara Kermarec
|
||||||
# Copyright © 2017 Augustin Lemesle
|
# Copyright © 2017 Augustin Lemesle
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -29,54 +29,100 @@ import django.db.models.deletion
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("users", "0005_auto_20160702_0006")]
|
||||||
('users', '0005_auto_20160702_0006'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Article',
|
name="Article",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(verbose_name='ID', auto_created=True, primary_key=True, serialize=False)),
|
(
|
||||||
('name', models.CharField(max_length=255)),
|
"id",
|
||||||
('prix', models.DecimalField(decimal_places=2, max_digits=5)),
|
models.AutoField(
|
||||||
|
verbose_name="ID",
|
||||||
|
auto_created=True,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("name", models.CharField(max_length=255)),
|
||||||
|
("prix", models.DecimalField(decimal_places=2, max_digits=5)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Banque',
|
name="Banque",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(verbose_name='ID', auto_created=True, primary_key=True, serialize=False)),
|
(
|
||||||
('name', models.CharField(max_length=255)),
|
"id",
|
||||||
|
models.AutoField(
|
||||||
|
verbose_name="ID",
|
||||||
|
auto_created=True,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("name", models.CharField(max_length=255)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Facture',
|
name="Facture",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(verbose_name='ID', auto_created=True, primary_key=True, serialize=False)),
|
(
|
||||||
('cheque', models.CharField(max_length=255)),
|
"id",
|
||||||
('number', models.IntegerField()),
|
models.AutoField(
|
||||||
('date', models.DateTimeField(auto_now_add=True)),
|
verbose_name="ID",
|
||||||
('name', models.CharField(max_length=255)),
|
auto_created=True,
|
||||||
('prix', models.DecimalField(decimal_places=2, max_digits=5)),
|
primary_key=True,
|
||||||
('article', models.ForeignKey(to='cotisations.Article', on_delete=django.db.models.deletion.PROTECT)),
|
serialize=False,
|
||||||
('banque', models.ForeignKey(to='cotisations.Banque', on_delete=django.db.models.deletion.PROTECT)),
|
),
|
||||||
|
),
|
||||||
|
("cheque", models.CharField(max_length=255)),
|
||||||
|
("number", models.IntegerField()),
|
||||||
|
("date", models.DateTimeField(auto_now_add=True)),
|
||||||
|
("name", models.CharField(max_length=255)),
|
||||||
|
("prix", models.DecimalField(decimal_places=2, max_digits=5)),
|
||||||
|
(
|
||||||
|
"article",
|
||||||
|
models.ForeignKey(
|
||||||
|
to="cotisations.Article",
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"banque",
|
||||||
|
models.ForeignKey(
|
||||||
|
to="cotisations.Banque",
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Paiement',
|
name="Paiement",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(verbose_name='ID', auto_created=True, primary_key=True, serialize=False)),
|
(
|
||||||
('moyen', models.CharField(max_length=255)),
|
"id",
|
||||||
|
models.AutoField(
|
||||||
|
verbose_name="ID",
|
||||||
|
auto_created=True,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("moyen", models.CharField(max_length=255)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='paiement',
|
name="paiement",
|
||||||
field=models.ForeignKey(to='cotisations.Paiement', on_delete=django.db.models.deletion.PROTECT),
|
field=models.ForeignKey(
|
||||||
|
to="cotisations.Paiement", on_delete=django.db.models.deletion.PROTECT
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='user',
|
name="user",
|
||||||
field=models.ForeignKey(to='users.User', on_delete=django.db.models.deletion.PROTECT),
|
field=models.ForeignKey(
|
||||||
|
to="users.User", on_delete=django.db.models.deletion.PROTECT
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# quelques clics.
|
# quelques clics.
|
||||||
#
|
#
|
||||||
# Copyright © 2017 Gabriel Détraz
|
# Copyright © 2017 Gabriel Détraz
|
||||||
# Copyright © 2017 Goulven Kermarec
|
# Copyright © 2017 Lara Kermarec
|
||||||
# Copyright © 2017 Augustin Lemesle
|
# Copyright © 2017 Augustin Lemesle
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -28,13 +28,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0001_initial")]
|
||||||
('cotisations', '0001_initial'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [migrations.RemoveField(model_name="facture", name="article")]
|
||||||
migrations.RemoveField(
|
|
||||||
model_name='facture',
|
|
||||||
name='article',
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# quelques clics.
|
# quelques clics.
|
||||||
#
|
#
|
||||||
# Copyright © 2017 Gabriel Détraz
|
# Copyright © 2017 Gabriel Détraz
|
||||||
# Copyright © 2017 Goulven Kermarec
|
# Copyright © 2017 Lara Kermarec
|
||||||
# Copyright © 2017 Augustin Lemesle
|
# Copyright © 2017 Augustin Lemesle
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -29,14 +29,17 @@ import django.db.models.deletion
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0002_remove_facture_article")]
|
||||||
('cotisations', '0002_remove_facture_article'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='banque',
|
name="banque",
|
||||||
field=models.ForeignKey(blank=True, to='cotisations.Banque', on_delete=django.db.models.deletion.PROTECT, null=True),
|
field=models.ForeignKey(
|
||||||
),
|
blank=True,
|
||||||
|
to="cotisations.Banque",
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
null=True,
|
||||||
|
),
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# quelques clics.
|
# quelques clics.
|
||||||
#
|
#
|
||||||
# Copyright © 2017 Gabriel Détraz
|
# Copyright © 2017 Gabriel Détraz
|
||||||
# Copyright © 2017 Goulven Kermarec
|
# Copyright © 2017 Lara Kermarec
|
||||||
# Copyright © 2017 Augustin Lemesle
|
# Copyright © 2017 Augustin Lemesle
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -28,19 +28,17 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0003_auto_20160702_1448")]
|
||||||
('cotisations', '0003_auto_20160702_1448'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='name',
|
name="name",
|
||||||
field=models.CharField(null=True, max_length=255),
|
field=models.CharField(null=True, max_length=255),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='prix',
|
name="prix",
|
||||||
field=models.DecimalField(max_digits=5, null=True, decimal_places=2),
|
field=models.DecimalField(max_digits=5, null=True, decimal_places=2),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# quelques clics.
|
# quelques clics.
|
||||||
#
|
#
|
||||||
# Copyright © 2017 Gabriel Détraz
|
# Copyright © 2017 Gabriel Détraz
|
||||||
# Copyright © 2017 Goulven Kermarec
|
# Copyright © 2017 Lara Kermarec
|
||||||
# Copyright © 2017 Augustin Lemesle
|
# Copyright © 2017 Augustin Lemesle
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -28,14 +28,12 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0004_auto_20160702_1528")]
|
||||||
('cotisations', '0004_auto_20160702_1528'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='cheque',
|
name="cheque",
|
||||||
field=models.CharField(max_length=255, blank=True),
|
field=models.CharField(max_length=255, blank=True),
|
||||||
),
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# quelques clics.
|
# quelques clics.
|
||||||
#
|
#
|
||||||
# Copyright © 2017 Gabriel Détraz
|
# Copyright © 2017 Gabriel Détraz
|
||||||
# Copyright © 2017 Goulven Kermarec
|
# Copyright © 2017 Lara Kermarec
|
||||||
# Copyright © 2017 Augustin Lemesle
|
# Copyright © 2017 Augustin Lemesle
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -28,19 +28,19 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0005_auto_20160702_1532")]
|
||||||
('cotisations', '0005_auto_20160702_1532'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='name',
|
name="name",
|
||||||
field=models.CharField(null=True, default='plop', max_length=255),
|
field=models.CharField(null=True, default="plop", max_length=255),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='prix',
|
name="prix",
|
||||||
field=models.DecimalField(null=True, decimal_places=2, default=1, max_digits=5),
|
field=models.DecimalField(
|
||||||
|
null=True, decimal_places=2, default=1, max_digits=5
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# quelques clics.
|
# quelques clics.
|
||||||
#
|
#
|
||||||
# Copyright © 2017 Gabriel Détraz
|
# Copyright © 2017 Gabriel Détraz
|
||||||
# Copyright © 2017 Goulven Kermarec
|
# Copyright © 2017 Lara Kermarec
|
||||||
# Copyright © 2017 Augustin Lemesle
|
# Copyright © 2017 Augustin Lemesle
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -28,20 +28,18 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0006_auto_20160702_1534")]
|
||||||
('cotisations', '0006_auto_20160702_1534'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='name',
|
name="name",
|
||||||
field=models.CharField(default='plop', max_length=255),
|
field=models.CharField(default="plop", max_length=255),
|
||||||
preserve_default=False,
|
preserve_default=False,
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='prix',
|
name="prix",
|
||||||
field=models.DecimalField(default=1, max_digits=5, decimal_places=2),
|
field=models.DecimalField(default=1, max_digits=5, decimal_places=2),
|
||||||
preserve_default=False,
|
preserve_default=False,
|
||||||
),
|
),
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# quelques clics.
|
# quelques clics.
|
||||||
#
|
#
|
||||||
# Copyright © 2017 Gabriel Détraz
|
# Copyright © 2017 Gabriel Détraz
|
||||||
# Copyright © 2017 Goulven Kermarec
|
# Copyright © 2017 Lara Kermarec
|
||||||
# Copyright © 2017 Augustin Lemesle
|
# Copyright © 2017 Augustin Lemesle
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -30,43 +30,53 @@ import django.db.models.deletion
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('users', '0005_auto_20160702_0006'),
|
("users", "0005_auto_20160702_0006"),
|
||||||
('cotisations', '0007_auto_20160702_1543'),
|
("cotisations", "0007_auto_20160702_1543"),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Cotisation',
|
name="Cotisation",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(verbose_name='ID', primary_key=True, serialize=False, auto_created=True)),
|
(
|
||||||
('date_start', models.DateTimeField(auto_now_add=True)),
|
"id",
|
||||||
('date_end', models.DateTimeField()),
|
models.AutoField(
|
||||||
|
verbose_name="ID",
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
auto_created=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("date_start", models.DateTimeField(auto_now_add=True)),
|
||||||
|
("date_end", models.DateTimeField()),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='cotisation',
|
name="cotisation",
|
||||||
field=models.BooleanField(default=True),
|
field=models.BooleanField(default=True),
|
||||||
preserve_default=False,
|
preserve_default=False,
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='duration',
|
name="duration",
|
||||||
field=models.DurationField(blank=True, null=True),
|
field=models.DurationField(blank=True, null=True),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='facture',
|
model_name="facture", name="valid", field=models.BooleanField(default=True)
|
||||||
name='valid',
|
|
||||||
field=models.BooleanField(default=True),
|
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='cotisation',
|
model_name="cotisation",
|
||||||
name='facture',
|
name="facture",
|
||||||
field=models.ForeignKey(to='cotisations.Facture', on_delete=django.db.models.deletion.PROTECT),
|
field=models.ForeignKey(
|
||||||
|
to="cotisations.Facture", on_delete=django.db.models.deletion.PROTECT
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='cotisation',
|
model_name="cotisation",
|
||||||
name='user',
|
name="user",
|
||||||
field=models.ForeignKey(to='users.User', on_delete=django.db.models.deletion.PROTECT),
|
field=models.ForeignKey(
|
||||||
|
to="users.User", on_delete=django.db.models.deletion.PROTECT
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# quelques clics.
|
# quelques clics.
|
||||||
#
|
#
|
||||||
# Copyright © 2017 Gabriel Détraz
|
# Copyright © 2017 Gabriel Détraz
|
||||||
# Copyright © 2017 Goulven Kermarec
|
# Copyright © 2017 Lara Kermarec
|
||||||
# Copyright © 2017 Augustin Lemesle
|
# Copyright © 2017 Augustin Lemesle
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -28,13 +28,6 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0008_auto_20160702_1614")]
|
||||||
('cotisations', '0008_auto_20160702_1614'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [migrations.RemoveField(model_name="cotisation", name="user")]
|
||||||
migrations.RemoveField(
|
|
||||||
model_name='cotisation',
|
|
||||||
name='user',
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# quelques clics.
|
# quelques clics.
|
||||||
#
|
#
|
||||||
# Copyright © 2017 Gabriel Détraz
|
# Copyright © 2017 Gabriel Détraz
|
||||||
# Copyright © 2017 Goulven Kermarec
|
# Copyright © 2017 Lara Kermarec
|
||||||
# Copyright © 2017 Augustin Lemesle
|
# Copyright © 2017 Augustin Lemesle
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -28,18 +28,15 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0009_remove_cotisation_user")]
|
||||||
('cotisations', '0009_remove_cotisation_user'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.RemoveField(
|
migrations.RemoveField(model_name="article", name="duration"),
|
||||||
model_name='article',
|
|
||||||
name='duration',
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='duration',
|
name="duration",
|
||||||
field=models.IntegerField(null=True, help_text='Durée exprimée en mois entiers', blank=True),
|
field=models.IntegerField(
|
||||||
|
null=True, help_text="Durée exprimée en mois entiers", blank=True
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# quelques clics.
|
# quelques clics.
|
||||||
#
|
#
|
||||||
# Copyright © 2017 Gabriel Détraz
|
# Copyright © 2017 Gabriel Détraz
|
||||||
# Copyright © 2017 Goulven Kermarec
|
# Copyright © 2017 Lara Kermarec
|
||||||
# Copyright © 2017 Augustin Lemesle
|
# Copyright © 2017 Augustin Lemesle
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -28,14 +28,10 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0010_auto_20160702_1840")]
|
||||||
('cotisations', '0010_auto_20160702_1840'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='cotisation',
|
model_name="cotisation", name="date_start", field=models.DateTimeField()
|
||||||
name='date_start',
|
)
|
||||||
field=models.DateTimeField(),
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# quelques clics.
|
# quelques clics.
|
||||||
#
|
#
|
||||||
# Copyright © 2017 Gabriel Détraz
|
# Copyright © 2017 Gabriel Détraz
|
||||||
# Copyright © 2017 Goulven Kermarec
|
# Copyright © 2017 Lara Kermarec
|
||||||
# Copyright © 2017 Augustin Lemesle
|
# Copyright © 2017 Augustin Lemesle
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -29,14 +29,14 @@ import django.db.models.deletion
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0011_auto_20160702_1911")]
|
||||||
('cotisations', '0011_auto_20160702_1911'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='cotisation',
|
model_name="cotisation",
|
||||||
name='facture',
|
name="facture",
|
||||||
field=models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='cotisations.Facture'),
|
field=models.OneToOneField(
|
||||||
),
|
on_delete=django.db.models.deletion.PROTECT, to="cotisations.Facture"
|
||||||
|
),
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# quelques clics.
|
# quelques clics.
|
||||||
#
|
#
|
||||||
# Copyright © 2017 Gabriel Détraz
|
# Copyright © 2017 Gabriel Détraz
|
||||||
# Copyright © 2017 Goulven Kermarec
|
# Copyright © 2017 Lara Kermarec
|
||||||
# Copyright © 2017 Augustin Lemesle
|
# Copyright © 2017 Augustin Lemesle
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -29,32 +29,41 @@ import django.db.models.deletion
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0012_auto_20160704_0118")]
|
||||||
('cotisations', '0012_auto_20160704_0118'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Vente',
|
name="Vente",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
(
|
||||||
('name', models.CharField(max_length=255)),
|
"id",
|
||||||
('prix', models.DecimalField(decimal_places=2, max_digits=5)),
|
models.AutoField(
|
||||||
('cotisation', models.BooleanField()),
|
auto_created=True,
|
||||||
('duration', models.IntegerField(null=True, blank=True, help_text='Durée exprimée en mois entiers')),
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
verbose_name="ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("name", models.CharField(max_length=255)),
|
||||||
|
("prix", models.DecimalField(decimal_places=2, max_digits=5)),
|
||||||
|
("cotisation", models.BooleanField()),
|
||||||
|
(
|
||||||
|
"duration",
|
||||||
|
models.IntegerField(
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
help_text="Durée exprimée en mois entiers",
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
migrations.RemoveField(
|
migrations.RemoveField(model_name="facture", name="name"),
|
||||||
model_name='facture',
|
migrations.RemoveField(model_name="facture", name="prix"),
|
||||||
name='name',
|
|
||||||
),
|
|
||||||
migrations.RemoveField(
|
|
||||||
model_name='facture',
|
|
||||||
name='prix',
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='facture',
|
name="facture",
|
||||||
field=models.ForeignKey(to='cotisations.Facture', on_delete=django.db.models.deletion.PROTECT),
|
field=models.ForeignKey(
|
||||||
|
to="cotisations.Facture", on_delete=django.db.models.deletion.PROTECT
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# quelques clics.
|
# quelques clics.
|
||||||
#
|
#
|
||||||
# Copyright © 2017 Gabriel Détraz
|
# Copyright © 2017 Gabriel Détraz
|
||||||
# Copyright © 2017 Goulven Kermarec
|
# Copyright © 2017 Lara Kermarec
|
||||||
# Copyright © 2017 Augustin Lemesle
|
# Copyright © 2017 Augustin Lemesle
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -28,18 +28,13 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0013_auto_20160711_2240")]
|
||||||
('cotisations', '0013_auto_20160711_2240'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.RemoveField(
|
migrations.RemoveField(model_name="facture", name="number"),
|
||||||
model_name='facture',
|
|
||||||
name='number',
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='number',
|
name="number",
|
||||||
field=models.IntegerField(default=1),
|
field=models.IntegerField(default=1),
|
||||||
preserve_default=False,
|
preserve_default=False,
|
||||||
),
|
),
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# quelques clics.
|
# quelques clics.
|
||||||
#
|
#
|
||||||
# Copyright © 2017 Gabriel Détraz
|
# Copyright © 2017 Gabriel Détraz
|
||||||
# Copyright © 2017 Goulven Kermarec
|
# Copyright © 2017 Lara Kermarec
|
||||||
# Copyright © 2017 Augustin Lemesle
|
# Copyright © 2017 Augustin Lemesle
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -29,29 +29,29 @@ import django.core.validators
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0014_auto_20160712_0245")]
|
||||||
('cotisations', '0014_auto_20160712_0245'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='control',
|
name="control",
|
||||||
field=models.BooleanField(default=False),
|
field=models.BooleanField(default=False),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='cotisation',
|
model_name="cotisation",
|
||||||
name='facture',
|
name="facture",
|
||||||
field=models.OneToOneField(to='cotisations.Facture'),
|
field=models.OneToOneField(to="cotisations.Facture"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='facture',
|
name="facture",
|
||||||
field=models.ForeignKey(to='cotisations.Facture'),
|
field=models.ForeignKey(to="cotisations.Facture"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='number',
|
name="number",
|
||||||
field=models.IntegerField(validators=[django.core.validators.MinValueValidator(1)]),
|
field=models.IntegerField(
|
||||||
|
validators=[django.core.validators.MinValueValidator(1)]
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# quelques clics.
|
# quelques clics.
|
||||||
#
|
#
|
||||||
# Copyright © 2017 Gabriel Détraz
|
# Copyright © 2017 Gabriel Détraz
|
||||||
# Copyright © 2017 Goulven Kermarec
|
# Copyright © 2017 Lara Kermarec
|
||||||
# Copyright © 2017 Augustin Lemesle
|
# Copyright © 2017 Augustin Lemesle
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -28,29 +28,20 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0015_auto_20160714_2142")]
|
||||||
('cotisations', '0015_auto_20160714_2142'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.RenameField(
|
migrations.RenameField(
|
||||||
model_name='article',
|
model_name="article", old_name="cotisation", new_name="iscotisation"
|
||||||
old_name='cotisation',
|
|
||||||
new_name='iscotisation',
|
|
||||||
),
|
),
|
||||||
migrations.RenameField(
|
migrations.RenameField(
|
||||||
model_name='vente',
|
model_name="vente", old_name="cotisation", new_name="iscotisation"
|
||||||
old_name='cotisation',
|
|
||||||
new_name='iscotisation',
|
|
||||||
),
|
|
||||||
migrations.RemoveField(
|
|
||||||
model_name='cotisation',
|
|
||||||
name='facture',
|
|
||||||
),
|
),
|
||||||
|
migrations.RemoveField(model_name="cotisation", name="facture"),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='cotisation',
|
model_name="cotisation",
|
||||||
name='vente',
|
name="vente",
|
||||||
field=models.OneToOneField(to='cotisations.Vente', null=True),
|
field=models.OneToOneField(to="cotisations.Vente", null=True),
|
||||||
preserve_default=False,
|
preserve_default=False,
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -8,19 +8,22 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0016_auto_20160715_0110")]
|
||||||
('cotisations', '0016_auto_20160715_0110'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='duration',
|
name="duration",
|
||||||
field=models.IntegerField(blank=True, help_text='Durée exprimée en mois entiers', null=True, validators=[django.core.validators.MinValueValidator(0)]),
|
field=models.IntegerField(
|
||||||
|
blank=True,
|
||||||
|
help_text="Durée exprimée en mois entiers",
|
||||||
|
null=True,
|
||||||
|
validators=[django.core.validators.MinValueValidator(0)],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='name',
|
name="name",
|
||||||
field=models.CharField(max_length=255, unique=True),
|
field=models.CharField(max_length=255, unique=True),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,15 +7,17 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0017_auto_20170718_2329")]
|
||||||
('cotisations', '0017_auto_20170718_2329'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='paiement',
|
model_name="paiement",
|
||||||
name='type_paiement',
|
name="type_paiement",
|
||||||
field=models.CharField(choices=[('check', 'Chèque'), (None, 'Autre')], default=None, max_length=255),
|
field=models.CharField(
|
||||||
|
choices=[("check", "Chèque"), (None, "Autre")],
|
||||||
|
default=None,
|
||||||
|
max_length=255,
|
||||||
|
),
|
||||||
preserve_default=False,
|
preserve_default=False,
|
||||||
),
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,14 +7,14 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0018_paiement_type_paiement")]
|
||||||
('cotisations', '0018_paiement_type_paiement'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='paiement',
|
model_name="paiement",
|
||||||
name='type_paiement',
|
name="type_paiement",
|
||||||
field=models.CharField(choices=[(0, 'Autre'), (1, 'Chèque')], default=0, max_length=255),
|
field=models.CharField(
|
||||||
),
|
choices=[(0, "Autre"), (1, "Chèque")], default=0, max_length=255
|
||||||
|
),
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,14 +7,14 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0019_auto_20170819_0055")]
|
||||||
('cotisations', '0019_auto_20170819_0055'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='paiement',
|
model_name="paiement",
|
||||||
name='type_paiement',
|
name="type_paiement",
|
||||||
field=models.IntegerField(choices=[(0, 'Autre'), (1, 'Chèque')], default=0, max_length=255),
|
field=models.IntegerField(
|
||||||
),
|
choices=[(0, "Autre"), (1, "Chèque")], default=0, max_length=255
|
||||||
|
),
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,14 +7,12 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0020_auto_20170819_0057")]
|
||||||
('cotisations', '0020_auto_20170819_0057'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='paiement',
|
model_name="paiement",
|
||||||
name='type_paiement',
|
name="type_paiement",
|
||||||
field=models.IntegerField(choices=[(0, 'Autre'), (1, 'Chèque')], default=0),
|
field=models.IntegerField(choices=[(0, "Autre"), (1, "Chèque")], default=0),
|
||||||
),
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,14 +7,14 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0021_auto_20170819_0104")]
|
||||||
('cotisations', '0021_auto_20170819_0104'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='paiement',
|
model_name="paiement",
|
||||||
name='type_paiement',
|
name="type_paiement",
|
||||||
field=models.IntegerField(choices=[(0, 'Autre'), (1, 'Chèque')], default=0, max_length=255),
|
field=models.IntegerField(
|
||||||
),
|
choices=[(0, "Autre"), (1, "Chèque")], default=0, max_length=255
|
||||||
|
),
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,14 +7,12 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0022_auto_20170824_0128")]
|
||||||
('cotisations', '0022_auto_20170824_0128'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='paiement',
|
model_name="paiement",
|
||||||
name='type_paiement',
|
name="type_paiement",
|
||||||
field=models.IntegerField(choices=[(0, 'Autre'), (1, 'Chèque')], default=0),
|
field=models.IntegerField(choices=[(0, "Autre"), (1, "Chèque")], default=0),
|
||||||
),
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -8,19 +8,24 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0023_auto_20170902_1303")]
|
||||||
('cotisations', '0023_auto_20170902_1303'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='duration',
|
name="duration",
|
||||||
field=models.PositiveIntegerField(blank=True, help_text='Durée exprimée en mois entiers', null=True, validators=[django.core.validators.MinValueValidator(0)]),
|
field=models.PositiveIntegerField(
|
||||||
|
blank=True,
|
||||||
|
help_text="Durée exprimée en mois entiers",
|
||||||
|
null=True,
|
||||||
|
validators=[django.core.validators.MinValueValidator(0)],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='duration',
|
name="duration",
|
||||||
field=models.PositiveIntegerField(blank=True, help_text='Durée exprimée en mois entiers', null=True),
|
field=models.PositiveIntegerField(
|
||||||
|
blank=True, help_text="Durée exprimée en mois entiers", null=True
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,14 +7,16 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0024_auto_20171015_2033")]
|
||||||
('cotisations', '0024_auto_20171015_2033'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='type_user',
|
name="type_user",
|
||||||
field=models.CharField(choices=[('Adherent', 'Adherent'), ('Club', 'Club'), ('All', 'All')], default='All', max_length=255),
|
field=models.CharField(
|
||||||
),
|
choices=[("Adherent", "Adherent"), ("Club", "Club"), ("All", "All")],
|
||||||
|
default="All",
|
||||||
|
max_length=255,
|
||||||
|
),
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -6,73 +6,94 @@ from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
def create_type(apps, schema_editor):
|
def create_type(apps, schema_editor):
|
||||||
Cotisation = apps.get_model('cotisations', 'Cotisation')
|
Cotisation = apps.get_model("cotisations", "Cotisation")
|
||||||
Vente = apps.get_model('cotisations', 'Vente')
|
Vente = apps.get_model("cotisations", "Vente")
|
||||||
Article = apps.get_model('cotisations', 'Article')
|
Article = apps.get_model("cotisations", "Article")
|
||||||
db_alias = schema_editor.connection.alias
|
db_alias = schema_editor.connection.alias
|
||||||
articles = Article.objects.using(db_alias).all()
|
articles = Article.objects.using(db_alias).all()
|
||||||
ventes = Vente.objects.using(db_alias).all()
|
ventes = Vente.objects.using(db_alias).all()
|
||||||
cotisations = Cotisation.objects.using(db_alias).all()
|
cotisations = Cotisation.objects.using(db_alias).all()
|
||||||
for article in articles:
|
for article in articles:
|
||||||
if article.iscotisation:
|
if article.iscotisation:
|
||||||
article.type_cotisation='All'
|
article.type_cotisation = "All"
|
||||||
article.save(using=db_alias)
|
article.save(using=db_alias)
|
||||||
for vente in ventes:
|
for vente in ventes:
|
||||||
if vente.iscotisation:
|
if vente.iscotisation:
|
||||||
vente.type_cotisation='All'
|
vente.type_cotisation = "All"
|
||||||
vente.save(using=db_alias)
|
vente.save(using=db_alias)
|
||||||
for cotisation in cotisations:
|
for cotisation in cotisations:
|
||||||
cotisation.type_cotisation='All'
|
cotisation.type_cotisation = "All"
|
||||||
cotisation.save(using=db_alias)
|
cotisation.save(using=db_alias)
|
||||||
|
|
||||||
|
|
||||||
def delete_type(apps, schema_editor):
|
def delete_type(apps, schema_editor):
|
||||||
Vente = apps.get_model('cotisations', 'Vente')
|
Vente = apps.get_model("cotisations", "Vente")
|
||||||
Article = apps.get_model('cotisations', 'Article')
|
Article = apps.get_model("cotisations", "Article")
|
||||||
db_alias = schema_editor.connection.alias
|
db_alias = schema_editor.connection.alias
|
||||||
articles = Articles.objects.using(db_alias).all()
|
articles = Article.objects.using(db_alias).all()
|
||||||
ventes = Vente.objects.using(db_alias).all()
|
ventes = Vente.objects.using(db_alias).all()
|
||||||
for article in articles:
|
for article in articles:
|
||||||
if article.type_cotisation:
|
if article.type_cotisation:
|
||||||
article.iscotisation=True
|
article.iscotisation = True
|
||||||
else:
|
else:
|
||||||
article.iscotisation=False
|
article.iscotisation = False
|
||||||
article.save(using=db_alias)
|
article.save(using=db_alias)
|
||||||
for vente in ventes:
|
for vente in ventes:
|
||||||
if vente.iscotisation:
|
if vente.iscotisation:
|
||||||
vente.iscotisation=True
|
vente.iscotisation = True
|
||||||
else:
|
else:
|
||||||
vente.iscotisation=False
|
vente.iscotisation = False
|
||||||
vente.save(using=db_alias)
|
vente.save(using=db_alias)
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0025_article_type_user")]
|
||||||
('cotisations', '0025_article_type_user'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='type_cotisation',
|
name="type_cotisation",
|
||||||
field=models.CharField(blank=True, choices=[('Connexion', 'Connexion'), ('Adhesion', 'Adhesion'), ('All', 'All')], default=None, max_length=255, null=True),
|
field=models.CharField(
|
||||||
|
blank=True,
|
||||||
|
choices=[
|
||||||
|
("Connexion", "Connexion"),
|
||||||
|
("Adhesion", "Adhesion"),
|
||||||
|
("All", "All"),
|
||||||
|
],
|
||||||
|
default=None,
|
||||||
|
max_length=255,
|
||||||
|
null=True,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='cotisation',
|
model_name="cotisation",
|
||||||
name='type_cotisation',
|
name="type_cotisation",
|
||||||
field=models.CharField(choices=[('Connexion', 'Connexion'), ('Adhesion', 'Adhesion'), ('All', 'All')], max_length=255, default='All'),
|
field=models.CharField(
|
||||||
|
choices=[
|
||||||
|
("Connexion", "Connexion"),
|
||||||
|
("Adhesion", "Adhesion"),
|
||||||
|
("All", "All"),
|
||||||
|
],
|
||||||
|
max_length=255,
|
||||||
|
default="All",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='type_cotisation',
|
name="type_cotisation",
|
||||||
field=models.CharField(blank=True, choices=[('Connexion', 'Connexion'), ('Adhesion', 'Adhesion'), ('All', 'All')], max_length=255, null=True),
|
field=models.CharField(
|
||||||
|
blank=True,
|
||||||
|
choices=[
|
||||||
|
("Connexion", "Connexion"),
|
||||||
|
("Adhesion", "Adhesion"),
|
||||||
|
("All", "All"),
|
||||||
|
],
|
||||||
|
max_length=255,
|
||||||
|
null=True,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.RunPython(create_type, delete_type),
|
migrations.RunPython(create_type, delete_type),
|
||||||
migrations.RemoveField(
|
migrations.RemoveField(model_name="article", name="iscotisation"),
|
||||||
model_name='article',
|
migrations.RemoveField(model_name="vente", name="iscotisation"),
|
||||||
name='iscotisation',
|
|
||||||
),
|
|
||||||
migrations.RemoveField(
|
|
||||||
model_name='vente',
|
|
||||||
name='iscotisation',
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,14 +7,10 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0026_auto_20171028_0126")]
|
||||||
('cotisations', '0026_auto_20171028_0126'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name="article", name="name", field=models.CharField(max_length=255)
|
||||||
name='name',
|
)
|
||||||
field=models.CharField(max_length=255),
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,33 +7,56 @@ from django.db import migrations
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0027_auto_20171029_1156")]
|
||||||
('cotisations', '0027_auto_20171029_1156'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='article',
|
name="article",
|
||||||
options={'permissions': (('view_article', 'Peut voir un objet article'),)},
|
options={"permissions": (("view_article", "Peut voir un objet article"),)},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='banque',
|
name="banque",
|
||||||
options={'permissions': (('view_banque', 'Peut voir un objet banque'),)},
|
options={"permissions": (("view_banque", "Peut voir un objet banque"),)},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='cotisation',
|
name="cotisation",
|
||||||
options={'permissions': (('view_cotisation', 'Peut voir un objet cotisation'), ('change_all_cotisation', 'Superdroit, peut modifier toutes les cotisations'))},
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("view_cotisation", "Peut voir un objet cotisation"),
|
||||||
|
(
|
||||||
|
"change_all_cotisation",
|
||||||
|
"Superdroit, peut modifier toutes les cotisations",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='facture',
|
name="facture",
|
||||||
options={'permissions': (('change_facture_control', "Peut changer l'etat de controle"), ('change_facture_pdf', 'Peut éditer une facture pdf'), ('view_facture', 'Peut voir un objet facture'), ('change_all_facture', 'Superdroit, peut modifier toutes les factures'))},
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("change_facture_control", "Peut changer l'etat de controle"),
|
||||||
|
("change_facture_pdf", "Peut éditer une facture pdf"),
|
||||||
|
("view_facture", "Peut voir un objet facture"),
|
||||||
|
(
|
||||||
|
"change_all_facture",
|
||||||
|
"Superdroit, peut modifier toutes les factures",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='paiement',
|
name="paiement",
|
||||||
options={'permissions': (('view_paiement', 'Peut voir un objet paiement'),)},
|
options={
|
||||||
|
"permissions": (("view_paiement", "Peut voir un objet paiement"),)
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='vente',
|
name="vente",
|
||||||
options={'permissions': (('view_vente', 'Peut voir un objet vente'), ('change_all_vente', 'Superdroit, peut modifier toutes les ventes'))},
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("view_vente", "Peut voir un objet vente"),
|
||||||
|
("change_all_vente", "Superdroit, peut modifier toutes les ventes"),
|
||||||
|
)
|
||||||
|
},
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -9,143 +9,242 @@ import django.db.models.deletion
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0028_auto_20171231_0007")]
|
||||||
('cotisations', '0028_auto_20171231_0007'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='article',
|
name="article",
|
||||||
options={'permissions': (('view_article', "Can see an article's details"),), 'verbose_name': 'Article', 'verbose_name_plural': 'Articles'},
|
options={
|
||||||
|
"permissions": (("view_article", "Can see an article's details"),),
|
||||||
|
"verbose_name": "Article",
|
||||||
|
"verbose_name_plural": "Articles",
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='banque',
|
name="banque",
|
||||||
options={'permissions': (('view_banque', "Can see a bank's details"),), 'verbose_name': 'Bank', 'verbose_name_plural': 'Banks'},
|
options={
|
||||||
|
"permissions": (("view_banque", "Can see a bank's details"),),
|
||||||
|
"verbose_name": "Bank",
|
||||||
|
"verbose_name_plural": "Banks",
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='cotisation',
|
name="cotisation",
|
||||||
options={'permissions': (('view_cotisation', "Can see a cotisation's details"), ('change_all_cotisation', 'Can edit the previous cotisations'))},
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("view_cotisation", "Can see a cotisation's details"),
|
||||||
|
("change_all_cotisation", "Can edit the previous cotisations"),
|
||||||
|
)
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='facture',
|
name="facture",
|
||||||
options={'permissions': (('change_facture_control', 'Can change the "controlled" state'), ('change_facture_pdf', 'Can create a custom PDF invoice'), ('view_facture', "Can see an invoice's details"), ('change_all_facture', 'Can edit all the previous invoices')), 'verbose_name': 'Invoice', 'verbose_name_plural': 'Invoices'},
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("change_facture_control", 'Can change the "controlled" state'),
|
||||||
|
("change_facture_pdf", "Can create a custom PDF invoice"),
|
||||||
|
("view_facture", "Can see an invoice's details"),
|
||||||
|
("change_all_facture", "Can edit all the previous invoices"),
|
||||||
|
),
|
||||||
|
"verbose_name": "Invoice",
|
||||||
|
"verbose_name_plural": "Invoices",
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='paiement',
|
name="paiement",
|
||||||
options={'permissions': (('view_paiement', "Can see a payement's details"),), 'verbose_name': 'Payment method', 'verbose_name_plural': 'Payment methods'},
|
options={
|
||||||
|
"permissions": (("view_paiement", "Can see a payement's details"),),
|
||||||
|
"verbose_name": "Payment method",
|
||||||
|
"verbose_name_plural": "Payment methods",
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='vente',
|
name="vente",
|
||||||
options={'permissions': (('view_vente', "Can see a purchase's details"), ('change_all_vente', 'Can edit all the previous purchases')), 'verbose_name': 'Purchase', 'verbose_name_plural': 'Purchases'},
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("view_vente", "Can see a purchase's details"),
|
||||||
|
("change_all_vente", "Can edit all the previous purchases"),
|
||||||
|
),
|
||||||
|
"verbose_name": "Purchase",
|
||||||
|
"verbose_name_plural": "Purchases",
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='duration',
|
name="duration",
|
||||||
field=models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Duration (in whole month)'),
|
field=models.PositiveIntegerField(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
validators=[django.core.validators.MinValueValidator(0)],
|
||||||
|
verbose_name="Duration (in whole month)",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='name',
|
name="name",
|
||||||
field=models.CharField(max_length=255, verbose_name='Designation'),
|
field=models.CharField(max_length=255, verbose_name="Designation"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='prix',
|
name="prix",
|
||||||
field=models.DecimalField(decimal_places=2, max_digits=5, verbose_name='Unitary price'),
|
field=models.DecimalField(
|
||||||
|
decimal_places=2, max_digits=5, verbose_name="Unitary price"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='type_cotisation',
|
name="type_cotisation",
|
||||||
field=models.CharField(blank=True, choices=[('Connexion', 'Connexion'), ('Adhesion', 'Membership'), ('All', 'Both of them')], default=None, max_length=255, null=True, verbose_name='Type of cotisation'),
|
field=models.CharField(
|
||||||
|
blank=True,
|
||||||
|
choices=[
|
||||||
|
("Connexion", "Connexion"),
|
||||||
|
("Adhesion", "Membership"),
|
||||||
|
("All", "Both of them"),
|
||||||
|
],
|
||||||
|
default=None,
|
||||||
|
max_length=255,
|
||||||
|
null=True,
|
||||||
|
verbose_name="Type of cotisation",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='type_user',
|
name="type_user",
|
||||||
field=models.CharField(choices=[('Adherent', 'Member'), ('Club', 'Club'), ('All', 'Both of them')], default='All', max_length=255, verbose_name='Type of users concerned'),
|
field=models.CharField(
|
||||||
|
choices=[
|
||||||
|
("Adherent", "Member"),
|
||||||
|
("Club", "Club"),
|
||||||
|
("All", "Both of them"),
|
||||||
|
],
|
||||||
|
default="All",
|
||||||
|
max_length=255,
|
||||||
|
verbose_name="Type of users concerned",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='banque',
|
model_name="banque",
|
||||||
name='name',
|
name="name",
|
||||||
field=models.CharField(max_length=255, verbose_name='Name'),
|
field=models.CharField(max_length=255, verbose_name="Name"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='cotisation',
|
model_name="cotisation",
|
||||||
name='date_end',
|
name="date_end",
|
||||||
field=models.DateTimeField(verbose_name='Ending date'),
|
field=models.DateTimeField(verbose_name="Ending date"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='cotisation',
|
model_name="cotisation",
|
||||||
name='date_start',
|
name="date_start",
|
||||||
field=models.DateTimeField(verbose_name='Starting date'),
|
field=models.DateTimeField(verbose_name="Starting date"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='cotisation',
|
model_name="cotisation",
|
||||||
name='type_cotisation',
|
name="type_cotisation",
|
||||||
field=models.CharField(choices=[('Connexion', 'Connexion'), ('Adhesion', 'Membership'), ('All', 'Both of them')], default='All', max_length=255, verbose_name='Type of cotisation'),
|
field=models.CharField(
|
||||||
|
choices=[
|
||||||
|
("Connexion", "Connexion"),
|
||||||
|
("Adhesion", "Membership"),
|
||||||
|
("All", "Both of them"),
|
||||||
|
],
|
||||||
|
default="All",
|
||||||
|
max_length=255,
|
||||||
|
verbose_name="Type of cotisation",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='cotisation',
|
model_name="cotisation",
|
||||||
name='vente',
|
name="vente",
|
||||||
field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to='cotisations.Vente', verbose_name='Purchase'),
|
field=models.OneToOneField(
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
to="cotisations.Vente",
|
||||||
|
verbose_name="Purchase",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='cheque',
|
name="cheque",
|
||||||
field=models.CharField(blank=True, max_length=255, verbose_name='Cheque number'),
|
field=models.CharField(
|
||||||
|
blank=True, max_length=255, verbose_name="Cheque number"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='control',
|
name="control",
|
||||||
field=models.BooleanField(default=False, verbose_name='Controlled'),
|
field=models.BooleanField(default=False, verbose_name="Controlled"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='date',
|
name="date",
|
||||||
field=models.DateTimeField(auto_now_add=True, verbose_name='Date'),
|
field=models.DateTimeField(auto_now_add=True, verbose_name="Date"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='valid',
|
name="valid",
|
||||||
field=models.BooleanField(default=True, verbose_name='Validated'),
|
field=models.BooleanField(default=True, verbose_name="Validated"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='paiement',
|
model_name="paiement",
|
||||||
name='moyen',
|
name="moyen",
|
||||||
field=models.CharField(max_length=255, verbose_name='Method'),
|
field=models.CharField(max_length=255, verbose_name="Method"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='paiement',
|
model_name="paiement",
|
||||||
name='type_paiement',
|
name="type_paiement",
|
||||||
field=models.IntegerField(choices=[(0, 'Standard'), (1, 'Cheque')], default=0, verbose_name='Payment type'),
|
field=models.IntegerField(
|
||||||
|
choices=[(0, "Standard"), (1, "Cheque")],
|
||||||
|
default=0,
|
||||||
|
verbose_name="Payment type",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='duration',
|
name="duration",
|
||||||
field=models.PositiveIntegerField(blank=True, null=True, verbose_name='Duration (in whole month)'),
|
field=models.PositiveIntegerField(
|
||||||
|
blank=True, null=True, verbose_name="Duration (in whole month)"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='facture',
|
name="facture",
|
||||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cotisations.Facture', verbose_name='Invoice'),
|
field=models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
to="cotisations.Facture",
|
||||||
|
verbose_name="Invoice",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='name',
|
name="name",
|
||||||
field=models.CharField(max_length=255, verbose_name='Article'),
|
field=models.CharField(max_length=255, verbose_name="Article"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='number',
|
name="number",
|
||||||
field=models.IntegerField(validators=[django.core.validators.MinValueValidator(1)], verbose_name='Amount'),
|
field=models.IntegerField(
|
||||||
|
validators=[django.core.validators.MinValueValidator(1)],
|
||||||
|
verbose_name="Amount",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='prix',
|
name="prix",
|
||||||
field=models.DecimalField(decimal_places=2, max_digits=5, verbose_name='Price'),
|
field=models.DecimalField(
|
||||||
|
decimal_places=2, max_digits=5, verbose_name="Price"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='type_cotisation',
|
name="type_cotisation",
|
||||||
field=models.CharField(blank=True, choices=[('Connexion', 'Connexion'), ('Adhesion', 'Membership'), ('All', 'Both of them')], max_length=255, null=True, verbose_name='Type of cotisation'),
|
field=models.CharField(
|
||||||
|
blank=True,
|
||||||
|
choices=[
|
||||||
|
("Connexion", "Connexion"),
|
||||||
|
("Adhesion", "Membership"),
|
||||||
|
("All", "Both of them"),
|
||||||
|
],
|
||||||
|
max_length=255,
|
||||||
|
null=True,
|
||||||
|
verbose_name="Type of cotisation",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -9,8 +9,8 @@ import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
def add_cheque(apps, schema_editor):
|
def add_cheque(apps, schema_editor):
|
||||||
ChequePayment = apps.get_model('cotisations', 'ChequePayment')
|
ChequePayment = apps.get_model("cotisations", "ChequePayment")
|
||||||
Payment = apps.get_model('cotisations', 'Paiement')
|
Payment = apps.get_model("cotisations", "Paiement")
|
||||||
for p in Payment.objects.filter(type_paiement=1):
|
for p in Payment.objects.filter(type_paiement=1):
|
||||||
cheque = ChequePayment()
|
cheque = ChequePayment()
|
||||||
cheque.payment = p
|
cheque.payment = p
|
||||||
|
@ -18,14 +18,12 @@ def add_cheque(apps, schema_editor):
|
||||||
|
|
||||||
|
|
||||||
def add_comnpay(apps, schema_editor):
|
def add_comnpay(apps, schema_editor):
|
||||||
ComnpayPayment = apps.get_model('cotisations', 'ComnpayPayment')
|
ComnpayPayment = apps.get_model("cotisations", "ComnpayPayment")
|
||||||
Payment = apps.get_model('cotisations', 'Paiement')
|
Payment = apps.get_model("cotisations", "Paiement")
|
||||||
AssoOption = apps.get_model('preferences', 'AssoOption')
|
AssoOption = apps.get_model("preferences", "AssoOption")
|
||||||
options, _created = AssoOption.objects.get_or_create()
|
options, _created = AssoOption.objects.get_or_create()
|
||||||
try:
|
try:
|
||||||
payment = Payment.objects.get(
|
payment = Payment.objects.get(moyen="Rechargement en ligne")
|
||||||
moyen='Rechargement en ligne'
|
|
||||||
)
|
|
||||||
except Payment.DoesNotExist:
|
except Payment.DoesNotExist:
|
||||||
return
|
return
|
||||||
comnpay = ComnpayPayment()
|
comnpay = ComnpayPayment()
|
||||||
|
@ -38,11 +36,11 @@ def add_comnpay(apps, schema_editor):
|
||||||
|
|
||||||
|
|
||||||
def add_solde(apps, schema_editor):
|
def add_solde(apps, schema_editor):
|
||||||
OptionalUser = apps.get_model('preferences', 'OptionalUser')
|
OptionalUser = apps.get_model("preferences", "OptionalUser")
|
||||||
options, _created = OptionalUser.objects.get_or_create()
|
options, _created = OptionalUser.objects.get_or_create()
|
||||||
|
|
||||||
Payment = apps.get_model('cotisations', 'Paiement')
|
Payment = apps.get_model("cotisations", "Paiement")
|
||||||
BalancePayment = apps.get_model('cotisations', 'BalancePayment')
|
BalancePayment = apps.get_model("cotisations", "BalancePayment")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
solde = Payment.objects.get(moyen="solde")
|
solde = Payment.objects.get(moyen="solde")
|
||||||
|
@ -60,73 +58,191 @@ def add_solde(apps, schema_editor):
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('preferences', '0044_remove_payment_pass'),
|
("preferences", "0044_remove_payment_pass"),
|
||||||
('cotisations', '0029_auto_20180414_2056'),
|
("cotisations", "0029_auto_20180414_2056"),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='paiement',
|
name="paiement",
|
||||||
options={'permissions': (('view_paiement', "Can see a payement's details"), ('use_every_payment', 'Can use every payement')), 'verbose_name': 'Payment method', 'verbose_name_plural': 'Payment methods'},
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("view_paiement", "Can see a payement's details"),
|
||||||
|
("use_every_payment", "Can use every payement"),
|
||||||
|
),
|
||||||
|
"verbose_name": "Payment method",
|
||||||
|
"verbose_name_plural": "Payment methods",
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='article',
|
name="article",
|
||||||
options={'permissions': (('view_article', "Can see an article's details"), ('buy_every_article', 'Can buy every_article')), 'verbose_name': 'Article', 'verbose_name_plural': 'Articles'},
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("view_article", "Can see an article's details"),
|
||||||
|
("buy_every_article", "Can buy every_article"),
|
||||||
|
),
|
||||||
|
"verbose_name": "Article",
|
||||||
|
"verbose_name_plural": "Articles",
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='paiement',
|
model_name="paiement",
|
||||||
name='available_for_everyone',
|
name="available_for_everyone",
|
||||||
field=models.BooleanField(default=False, verbose_name='Is available for every user'),
|
field=models.BooleanField(
|
||||||
|
default=False, verbose_name="Is available for every user"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='paiement',
|
model_name="paiement",
|
||||||
name='is_balance',
|
name="is_balance",
|
||||||
field=models.BooleanField(default=False, editable=False, help_text='There should be only one balance payment method.', verbose_name='Is user balance', validators=[cotisations.models.check_no_balance]),
|
field=models.BooleanField(
|
||||||
|
default=False,
|
||||||
|
editable=False,
|
||||||
|
help_text="There should be only one balance payment method.",
|
||||||
|
verbose_name="Is user balance",
|
||||||
|
validators=[cotisations.models.check_no_balance],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='available_for_everyone',
|
name="available_for_everyone",
|
||||||
field=models.BooleanField(default=False, verbose_name='Is available for every user'),
|
field=models.BooleanField(
|
||||||
|
default=False, verbose_name="Is available for every user"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='ChequePayment',
|
name="ChequePayment",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
(
|
||||||
('payment', models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='payment_method', to='cotisations.Paiement')),
|
"id",
|
||||||
|
models.AutoField(
|
||||||
|
auto_created=True,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
verbose_name="ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"payment",
|
||||||
|
models.OneToOneField(
|
||||||
|
editable=False,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="payment_method",
|
||||||
|
to="cotisations.Paiement",
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
bases=(cotisations.payment_methods.mixins.PaymentMethodMixin, models.Model),
|
bases=(cotisations.payment_methods.mixins.PaymentMethodMixin, models.Model),
|
||||||
options={'verbose_name': 'Cheque'},
|
options={"verbose_name": "Cheque"},
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='ComnpayPayment',
|
name="ComnpayPayment",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
(
|
||||||
('payment_credential', models.CharField(blank=True, default='', max_length=255, verbose_name='ComNpay VAD Number')),
|
"id",
|
||||||
('payment_pass', re2o.aes_field.AESEncryptedField(blank=True, max_length=255, null=True, verbose_name='ComNpay Secret Key')),
|
models.AutoField(
|
||||||
('payment', models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='payment_method', to='cotisations.Paiement')),
|
auto_created=True,
|
||||||
('minimum_payment', models.DecimalField(decimal_places=2, default=1, help_text='The minimal amount of money you have to use when paying with ComNpay', max_digits=5, verbose_name='Minimum payment')),
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
verbose_name="ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"payment_credential",
|
||||||
|
models.CharField(
|
||||||
|
blank=True,
|
||||||
|
default="",
|
||||||
|
max_length=255,
|
||||||
|
verbose_name="ComNpay VAD Number",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"payment_pass",
|
||||||
|
re2o.aes_field.AESEncryptedField(
|
||||||
|
blank=True,
|
||||||
|
max_length=255,
|
||||||
|
null=True,
|
||||||
|
verbose_name="ComNpay Secret Key",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"payment",
|
||||||
|
models.OneToOneField(
|
||||||
|
editable=False,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="payment_method",
|
||||||
|
to="cotisations.Paiement",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"minimum_payment",
|
||||||
|
models.DecimalField(
|
||||||
|
decimal_places=2,
|
||||||
|
default=1,
|
||||||
|
help_text="The minimal amount of money you have to use when paying with ComNpay",
|
||||||
|
max_digits=5,
|
||||||
|
verbose_name="Minimum payment",
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
bases=(cotisations.payment_methods.mixins.PaymentMethodMixin, models.Model),
|
bases=(cotisations.payment_methods.mixins.PaymentMethodMixin, models.Model),
|
||||||
options={'verbose_name': 'ComNpay'},
|
options={"verbose_name": "ComNpay"},
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='BalancePayment',
|
name="BalancePayment",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
(
|
||||||
('minimum_balance', models.DecimalField(decimal_places=2, default=0, help_text='The minimal amount of money allowed for the balance at the end of a payment. You can specify negative amount.', max_digits=5, verbose_name='Minimum balance')),
|
"id",
|
||||||
('payment', models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='payment_method', to='cotisations.Paiement')),
|
models.AutoField(
|
||||||
('maximum_balance', models.DecimalField(decimal_places=2, default=50, help_text='The maximal amount of money allowed for the balance.', max_digits=5, verbose_name='Maximum balance', null=True, blank=True)),
|
auto_created=True,
|
||||||
('credit_balance_allowed', models.BooleanField(default=False, verbose_name='Allow user to credit their balance')),
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
verbose_name="ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"minimum_balance",
|
||||||
|
models.DecimalField(
|
||||||
|
decimal_places=2,
|
||||||
|
default=0,
|
||||||
|
help_text="The minimal amount of money allowed for the balance at the end of a payment. You can specify negative amount.",
|
||||||
|
max_digits=5,
|
||||||
|
verbose_name="Minimum balance",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"payment",
|
||||||
|
models.OneToOneField(
|
||||||
|
editable=False,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="payment_method",
|
||||||
|
to="cotisations.Paiement",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"maximum_balance",
|
||||||
|
models.DecimalField(
|
||||||
|
decimal_places=2,
|
||||||
|
default=50,
|
||||||
|
help_text="The maximal amount of money allowed for the balance.",
|
||||||
|
max_digits=5,
|
||||||
|
verbose_name="Maximum balance",
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"credit_balance_allowed",
|
||||||
|
models.BooleanField(
|
||||||
|
default=False, verbose_name="Allow user to credit their balance"
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
bases=(cotisations.payment_methods.mixins.PaymentMethodMixin, models.Model),
|
bases=(cotisations.payment_methods.mixins.PaymentMethodMixin, models.Model),
|
||||||
options={'verbose_name': 'User Balance'},
|
options={"verbose_name": "User Balance"},
|
||||||
),
|
),
|
||||||
migrations.RunPython(add_comnpay),
|
migrations.RunPython(add_comnpay),
|
||||||
migrations.RunPython(add_cheque),
|
migrations.RunPython(add_cheque),
|
||||||
migrations.RunPython(add_solde),
|
migrations.RunPython(add_solde),
|
||||||
migrations.RemoveField(
|
migrations.RemoveField(model_name="paiement", name="type_paiement"),
|
||||||
model_name='paiement',
|
|
||||||
name='type_paiement',
|
|
||||||
),
|
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,14 +7,15 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0030_custom_payment")]
|
||||||
('cotisations', '0030_custom_payment'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='comnpaypayment',
|
model_name="comnpaypayment",
|
||||||
name='production',
|
name="production",
|
||||||
field=models.BooleanField(default=True, verbose_name='Production mode enabled (production url, instead of homologation)'),
|
field=models.BooleanField(
|
||||||
),
|
default=True,
|
||||||
|
verbose_name="Production mode enabled (production url, instead of homologation)",
|
||||||
|
),
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -10,8 +10,8 @@ import re2o.mixins
|
||||||
|
|
||||||
|
|
||||||
def reattribute_ids(apps, schema_editor):
|
def reattribute_ids(apps, schema_editor):
|
||||||
Facture = apps.get_model('cotisations', 'Facture')
|
Facture = apps.get_model("cotisations", "Facture")
|
||||||
BaseInvoice = apps.get_model('cotisations', 'BaseInvoice')
|
BaseInvoice = apps.get_model("cotisations", "BaseInvoice")
|
||||||
|
|
||||||
for f in Facture.objects.all():
|
for f in Facture.objects.all():
|
||||||
base = BaseInvoice.objects.create(id=f.pk)
|
base = BaseInvoice.objects.create(id=f.pk)
|
||||||
|
@ -22,21 +22,23 @@ def reattribute_ids(apps, schema_editor):
|
||||||
|
|
||||||
|
|
||||||
def update_rights(apps, schema_editor):
|
def update_rights(apps, schema_editor):
|
||||||
Permission = apps.get_model('auth', 'Permission')
|
Permission = apps.get_model("auth", "Permission")
|
||||||
|
|
||||||
# creates needed permissions
|
# creates needed permissions
|
||||||
app = apps.get_app_config('cotisations')
|
app = apps.get_app_config("cotisations")
|
||||||
app.models_module = True
|
app.models_module = True
|
||||||
create_permissions(app)
|
create_permissions(app)
|
||||||
app.models_module = False
|
app.models_module = False
|
||||||
|
|
||||||
ContentType = apps.get_model("contenttypes", "ContentType")
|
ContentType = apps.get_model("contenttypes", "ContentType")
|
||||||
content_type = ContentType.objects.get_for_model(Permission)
|
content_type = ContentType.objects.get_for_model(Permission)
|
||||||
former, created = Permission.objects.get_or_create(codename='change_facture_pdf', content_type=content_type)
|
former, created = Permission.objects.get_or_create(
|
||||||
new_1 = Permission.objects.get(codename='add_custominvoice')
|
codename="change_facture_pdf", content_type=content_type
|
||||||
new_2 = Permission.objects.get(codename='change_custominvoice')
|
)
|
||||||
new_3 = Permission.objects.get(codename='view_custominvoice')
|
new_1 = Permission.objects.get(codename="add_custominvoice")
|
||||||
new_4 = Permission.objects.get(codename='delete_custominvoice')
|
new_2 = Permission.objects.get(codename="change_custominvoice")
|
||||||
|
new_3 = Permission.objects.get(codename="view_custominvoice")
|
||||||
|
new_4 = Permission.objects.get(codename="delete_custominvoice")
|
||||||
for group in former.group_set.all():
|
for group in former.group_set.all():
|
||||||
group.permissions.remove(former)
|
group.permissions.remove(former)
|
||||||
group.permissions.add(new_1)
|
group.permissions.add(new_1)
|
||||||
|
@ -48,59 +50,105 @@ def update_rights(apps, schema_editor):
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0031_comnpaypayment_production")]
|
||||||
('cotisations', '0031_comnpaypayment_production'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='BaseInvoice',
|
name="BaseInvoice",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
(
|
||||||
('date', models.DateTimeField(auto_now_add=True, verbose_name='Date')),
|
"id",
|
||||||
|
models.AutoField(
|
||||||
|
auto_created=True,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
verbose_name="ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("date", models.DateTimeField(auto_now_add=True, verbose_name="Date")),
|
||||||
],
|
],
|
||||||
bases=(re2o.mixins.RevMixin, re2o.mixins.AclMixin, re2o.field_permissions.FieldPermissionModelMixin, models.Model),
|
bases=(
|
||||||
|
re2o.mixins.RevMixin,
|
||||||
|
re2o.mixins.AclMixin,
|
||||||
|
re2o.field_permissions.FieldPermissionModelMixin,
|
||||||
|
models.Model,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='CustomInvoice',
|
name="CustomInvoice",
|
||||||
fields=[
|
fields=[
|
||||||
('baseinvoice_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='cotisations.BaseInvoice')),
|
(
|
||||||
('recipient', models.CharField(max_length=255, verbose_name='Recipient')),
|
"baseinvoice_ptr",
|
||||||
('payment', models.CharField(max_length=255, verbose_name='Payment type')),
|
models.OneToOneField(
|
||||||
('address', models.CharField(max_length=255, verbose_name='Address')),
|
auto_created=True,
|
||||||
('paid', models.BooleanField(verbose_name='Paid')),
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
parent_link=True,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
to="cotisations.BaseInvoice",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"recipient",
|
||||||
|
models.CharField(max_length=255, verbose_name="Recipient"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"payment",
|
||||||
|
models.CharField(max_length=255, verbose_name="Payment type"),
|
||||||
|
),
|
||||||
|
("address", models.CharField(max_length=255, verbose_name="Address")),
|
||||||
|
("paid", models.BooleanField(verbose_name="Paid")),
|
||||||
],
|
],
|
||||||
bases=('cotisations.baseinvoice',),
|
bases=("cotisations.baseinvoice",),
|
||||||
options={'permissions': (('view_custominvoice', 'Can view a custom invoice'),)},
|
options={
|
||||||
|
"permissions": (("view_custominvoice", "Can view a custom invoice"),)
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='baseinvoice_ptr',
|
name="baseinvoice_ptr",
|
||||||
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='cotisations.BaseInvoice', null=True),
|
field=models.OneToOneField(
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
to="cotisations.BaseInvoice",
|
||||||
|
null=True,
|
||||||
|
),
|
||||||
preserve_default=False,
|
preserve_default=False,
|
||||||
),
|
),
|
||||||
migrations.RunPython(reattribute_ids),
|
migrations.RunPython(reattribute_ids),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='facture',
|
name="facture",
|
||||||
field=models.ForeignKey(on_delete=models.CASCADE, verbose_name='Invoice', to='cotisations.BaseInvoice')
|
field=models.ForeignKey(
|
||||||
),
|
on_delete=models.CASCADE,
|
||||||
migrations.RemoveField(
|
verbose_name="Invoice",
|
||||||
model_name='facture',
|
to="cotisations.BaseInvoice",
|
||||||
name='id',
|
),
|
||||||
),
|
|
||||||
migrations.RemoveField(
|
|
||||||
model_name='facture',
|
|
||||||
name='date',
|
|
||||||
),
|
),
|
||||||
|
migrations.RemoveField(model_name="facture", name="id"),
|
||||||
|
migrations.RemoveField(model_name="facture", name="date"),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='baseinvoice_ptr',
|
name="baseinvoice_ptr",
|
||||||
field=models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='cotisations.BaseInvoice'),
|
field=models.OneToOneField(
|
||||||
|
auto_created=True,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
parent_link=True,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
to="cotisations.BaseInvoice",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.RunPython(update_rights),
|
migrations.RunPython(update_rights),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='facture',
|
name="facture",
|
||||||
options={'permissions': (('change_facture_control', 'Can change the "controlled" state'), ('view_facture', "Can see an invoice's details"), ('change_all_facture', 'Can edit all the previous invoices')), 'verbose_name': 'Invoice', 'verbose_name_plural': 'Invoices'},
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("change_facture_control", 'Can change the "controlled" state'),
|
||||||
|
("view_facture", "Can see an invoice's details"),
|
||||||
|
("change_all_facture", "Can edit all the previous invoices"),
|
||||||
|
),
|
||||||
|
"verbose_name": "Invoice",
|
||||||
|
"verbose_name_plural": "Invoices",
|
||||||
|
},
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -11,171 +11,294 @@ import re2o.aes_field
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0032_custom_invoice")]
|
||||||
('cotisations', '0032_custom_invoice'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='article',
|
name="article",
|
||||||
options={'permissions': (('view_article', 'Can view an article object'), ('buy_every_article', 'Can buy every article')), 'verbose_name': 'article', 'verbose_name_plural': 'articles'},
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("view_article", "Can view an article object"),
|
||||||
|
("buy_every_article", "Can buy every article"),
|
||||||
|
),
|
||||||
|
"verbose_name": "article",
|
||||||
|
"verbose_name_plural": "articles",
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='balancepayment',
|
name="balancepayment", options={"verbose_name": "user balance"}
|
||||||
options={'verbose_name': 'user balance'},
|
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='banque',
|
name="banque",
|
||||||
options={'permissions': (('view_banque', 'Can view a bank object'),), 'verbose_name': 'bank', 'verbose_name_plural': 'banks'},
|
options={
|
||||||
|
"permissions": (("view_banque", "Can view a bank object"),),
|
||||||
|
"verbose_name": "bank",
|
||||||
|
"verbose_name_plural": "banks",
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='cotisation',
|
name="cotisation",
|
||||||
options={'permissions': (('view_cotisation', 'Can view a subscription object'), ('change_all_cotisation', 'Can edit the previous subscriptions')), 'verbose_name': 'subscription', 'verbose_name_plural': 'subscriptions'},
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("view_cotisation", "Can view a subscription object"),
|
||||||
|
("change_all_cotisation", "Can edit the previous subscriptions"),
|
||||||
|
),
|
||||||
|
"verbose_name": "subscription",
|
||||||
|
"verbose_name_plural": "subscriptions",
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='custominvoice',
|
name="custominvoice",
|
||||||
options={'permissions': (('view_custominvoice', 'Can view a custom invoice object'),)},
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("view_custominvoice", "Can view a custom invoice object"),
|
||||||
|
)
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='facture',
|
name="facture",
|
||||||
options={'permissions': (('change_facture_control', 'Can edit the "controlled" state'), ('view_facture', 'Can view an invoice object'), ('change_all_facture', 'Can edit all the previous invoices')), 'verbose_name': 'invoice', 'verbose_name_plural': 'invoices'},
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("change_facture_control", 'Can edit the "controlled" state'),
|
||||||
|
("view_facture", "Can view an invoice object"),
|
||||||
|
("change_all_facture", "Can edit all the previous invoices"),
|
||||||
|
),
|
||||||
|
"verbose_name": "invoice",
|
||||||
|
"verbose_name_plural": "invoices",
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='paiement',
|
name="paiement",
|
||||||
options={'permissions': (('view_paiement', 'Can view a payment method object'), ('use_every_payment', 'Can use every payment method')), 'verbose_name': 'payment method', 'verbose_name_plural': 'payment methods'},
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("view_paiement", "Can view a payment method object"),
|
||||||
|
("use_every_payment", "Can use every payment method"),
|
||||||
|
),
|
||||||
|
"verbose_name": "payment method",
|
||||||
|
"verbose_name_plural": "payment methods",
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='vente',
|
name="vente",
|
||||||
options={'permissions': (('view_vente', 'Can view a purchase object'), ('change_all_vente', 'Can edit all the previous purchases')), 'verbose_name': 'purchase', 'verbose_name_plural': 'purchases'},
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("view_vente", "Can view a purchase object"),
|
||||||
|
("change_all_vente", "Can edit all the previous purchases"),
|
||||||
|
),
|
||||||
|
"verbose_name": "purchase",
|
||||||
|
"verbose_name_plural": "purchases",
|
||||||
|
},
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='available_for_everyone',
|
name="available_for_everyone",
|
||||||
field=models.BooleanField(default=False, verbose_name='is available for every user'),
|
field=models.BooleanField(
|
||||||
|
default=False, verbose_name="is available for every user"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='duration',
|
name="duration",
|
||||||
field=models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(0)], verbose_name='duration (in months)'),
|
field=models.PositiveIntegerField(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
validators=[django.core.validators.MinValueValidator(0)],
|
||||||
|
verbose_name="duration (in months)",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='name',
|
name="name",
|
||||||
field=models.CharField(max_length=255, verbose_name='designation'),
|
field=models.CharField(max_length=255, verbose_name="designation"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='prix',
|
name="prix",
|
||||||
field=models.DecimalField(decimal_places=2, max_digits=5, verbose_name='unit price'),
|
field=models.DecimalField(
|
||||||
|
decimal_places=2, max_digits=5, verbose_name="unit price"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='type_cotisation',
|
name="type_cotisation",
|
||||||
field=models.CharField(blank=True, choices=[('Connexion', 'Connection'), ('Adhesion', 'Membership'), ('All', 'Both of them')], default=None, max_length=255, null=True, verbose_name='subscription type'),
|
field=models.CharField(
|
||||||
|
blank=True,
|
||||||
|
choices=[
|
||||||
|
("Connexion", "Connection"),
|
||||||
|
("Adhesion", "Membership"),
|
||||||
|
("All", "Both of them"),
|
||||||
|
],
|
||||||
|
default=None,
|
||||||
|
max_length=255,
|
||||||
|
null=True,
|
||||||
|
verbose_name="subscription type",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='article',
|
model_name="article",
|
||||||
name='type_user',
|
name="type_user",
|
||||||
field=models.CharField(choices=[('Adherent', 'Member'), ('Club', 'Club'), ('All', 'Both of them')], default='All', max_length=255, verbose_name='type of users concerned'),
|
field=models.CharField(
|
||||||
|
choices=[
|
||||||
|
("Adherent", "Member"),
|
||||||
|
("Club", "Club"),
|
||||||
|
("All", "Both of them"),
|
||||||
|
],
|
||||||
|
default="All",
|
||||||
|
max_length=255,
|
||||||
|
verbose_name="type of users concerned",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='banque',
|
model_name="banque", name="name", field=models.CharField(max_length=255)
|
||||||
name='name',
|
|
||||||
field=models.CharField(max_length=255),
|
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='comnpaypayment',
|
model_name="comnpaypayment",
|
||||||
name='payment_credential',
|
name="payment_credential",
|
||||||
field=models.CharField(blank=True, default='', max_length=255, verbose_name='ComNpay VAT Number'),
|
field=models.CharField(
|
||||||
|
blank=True,
|
||||||
|
default="",
|
||||||
|
max_length=255,
|
||||||
|
verbose_name="ComNpay VAT Number",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='comnpaypayment',
|
model_name="comnpaypayment",
|
||||||
name='payment_pass',
|
name="payment_pass",
|
||||||
field=re2o.aes_field.AESEncryptedField(blank=True, max_length=255, null=True, verbose_name='ComNpay secret key'),
|
field=re2o.aes_field.AESEncryptedField(
|
||||||
|
blank=True, max_length=255, null=True, verbose_name="ComNpay secret key"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='comnpaypayment',
|
model_name="comnpaypayment",
|
||||||
name='production',
|
name="production",
|
||||||
field=models.BooleanField(default=True, verbose_name='Production mode enabled (production URL, instead of homologation)'),
|
field=models.BooleanField(
|
||||||
|
default=True,
|
||||||
|
verbose_name="Production mode enabled (production URL, instead of homologation)",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='cotisation',
|
model_name="cotisation",
|
||||||
name='date_end',
|
name="date_end",
|
||||||
field=models.DateTimeField(verbose_name='end date'),
|
field=models.DateTimeField(verbose_name="end date"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='cotisation',
|
model_name="cotisation",
|
||||||
name='date_start',
|
name="date_start",
|
||||||
field=models.DateTimeField(verbose_name='start date'),
|
field=models.DateTimeField(verbose_name="start date"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='cotisation',
|
model_name="cotisation",
|
||||||
name='type_cotisation',
|
name="type_cotisation",
|
||||||
field=models.CharField(choices=[('Connexion', 'Connection'), ('Adhesion', 'Membership'), ('All', 'Both of them')], default='All', max_length=255, verbose_name='subscription type'),
|
field=models.CharField(
|
||||||
|
choices=[
|
||||||
|
("Connexion", "Connection"),
|
||||||
|
("Adhesion", "Membership"),
|
||||||
|
("All", "Both of them"),
|
||||||
|
],
|
||||||
|
default="All",
|
||||||
|
max_length=255,
|
||||||
|
verbose_name="subscription type",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='cotisation',
|
model_name="cotisation",
|
||||||
name='vente',
|
name="vente",
|
||||||
field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to='cotisations.Vente', verbose_name='purchase'),
|
field=models.OneToOneField(
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
to="cotisations.Vente",
|
||||||
|
verbose_name="purchase",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='cheque',
|
name="cheque",
|
||||||
field=models.CharField(blank=True, max_length=255, verbose_name='cheque number'),
|
field=models.CharField(
|
||||||
|
blank=True, max_length=255, verbose_name="cheque number"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='control',
|
name="control",
|
||||||
field=models.BooleanField(default=False, verbose_name='controlled'),
|
field=models.BooleanField(default=False, verbose_name="controlled"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='valid',
|
name="valid",
|
||||||
field=models.BooleanField(default=True, verbose_name='validated'),
|
field=models.BooleanField(default=True, verbose_name="validated"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='paiement',
|
model_name="paiement",
|
||||||
name='available_for_everyone',
|
name="available_for_everyone",
|
||||||
field=models.BooleanField(default=False, verbose_name='is available for every user'),
|
field=models.BooleanField(
|
||||||
|
default=False, verbose_name="is available for every user"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='paiement',
|
model_name="paiement",
|
||||||
name='is_balance',
|
name="is_balance",
|
||||||
field=models.BooleanField(default=False, editable=False, help_text='There should be only one balance payment method.', validators=[cotisations.validators.check_no_balance], verbose_name='is user balance'),
|
field=models.BooleanField(
|
||||||
|
default=False,
|
||||||
|
editable=False,
|
||||||
|
help_text="There should be only one balance payment method.",
|
||||||
|
validators=[cotisations.validators.check_no_balance],
|
||||||
|
verbose_name="is user balance",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='paiement',
|
model_name="paiement",
|
||||||
name='moyen',
|
name="moyen",
|
||||||
field=models.CharField(max_length=255, verbose_name='method'),
|
field=models.CharField(max_length=255, verbose_name="method"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='duration',
|
name="duration",
|
||||||
field=models.PositiveIntegerField(blank=True, null=True, verbose_name='duration (in months)'),
|
field=models.PositiveIntegerField(
|
||||||
|
blank=True, null=True, verbose_name="duration (in months)"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='facture',
|
name="facture",
|
||||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cotisations.BaseInvoice', verbose_name='invoice'),
|
field=models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
to="cotisations.BaseInvoice",
|
||||||
|
verbose_name="invoice",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='name',
|
name="name",
|
||||||
field=models.CharField(max_length=255, verbose_name='article'),
|
field=models.CharField(max_length=255, verbose_name="article"),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='number',
|
name="number",
|
||||||
field=models.IntegerField(validators=[django.core.validators.MinValueValidator(1)], verbose_name='amount'),
|
field=models.IntegerField(
|
||||||
|
validators=[django.core.validators.MinValueValidator(1)],
|
||||||
|
verbose_name="amount",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='prix',
|
name="prix",
|
||||||
field=models.DecimalField(decimal_places=2, max_digits=5, verbose_name='price'),
|
field=models.DecimalField(
|
||||||
|
decimal_places=2, max_digits=5, verbose_name="price"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='vente',
|
model_name="vente",
|
||||||
name='type_cotisation',
|
name="type_cotisation",
|
||||||
field=models.CharField(blank=True, choices=[('Connexion', 'Connection'), ('Adhesion', 'Membership'), ('All', 'Both of them')], max_length=255, null=True, verbose_name='subscription type'),
|
field=models.CharField(
|
||||||
|
blank=True,
|
||||||
|
choices=[
|
||||||
|
("Connexion", "Connection"),
|
||||||
|
("Adhesion", "Membership"),
|
||||||
|
("All", "Both of them"),
|
||||||
|
],
|
||||||
|
max_length=255,
|
||||||
|
null=True,
|
||||||
|
verbose_name="subscription type",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,14 +7,12 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0033_auto_20180818_1319")]
|
||||||
('cotisations', '0033_auto_20180818_1319'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='facture',
|
model_name="facture",
|
||||||
name='valid',
|
name="valid",
|
||||||
field=models.BooleanField(default=False, verbose_name='validated'),
|
field=models.BooleanField(default=False, verbose_name="validated"),
|
||||||
),
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -9,23 +9,35 @@ import django.db.models.deletion
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0034_auto_20180831_1532")]
|
||||||
('cotisations', '0034_auto_20180831_1532'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='NotePayment',
|
name="NotePayment",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
(
|
||||||
('server', models.CharField(max_length=255, verbose_name='server')),
|
"id",
|
||||||
('port', models.PositiveIntegerField(blank=True, null=True)),
|
models.AutoField(
|
||||||
('id_note', models.PositiveIntegerField(blank=True, null=True)),
|
auto_created=True,
|
||||||
('payment', models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='payment_method', to='cotisations.Paiement')),
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
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={
|
options={"verbose_name": "NoteKfet"},
|
||||||
'verbose_name': 'NoteKfet',
|
|
||||||
},
|
|
||||||
bases=(cotisations.payment_methods.mixins.PaymentMethodMixin, models.Model),
|
bases=(cotisations.payment_methods.mixins.PaymentMethodMixin, models.Model),
|
||||||
),
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,14 +7,12 @@ from django.db import migrations, models
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0035_notepayment")]
|
||||||
('cotisations', '0035_notepayment'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='custominvoice',
|
model_name="custominvoice",
|
||||||
name='remark',
|
name="remark",
|
||||||
field=models.TextField(blank=True, null=True, verbose_name='Remark'),
|
field=models.TextField(blank=True, null=True, verbose_name="Remark"),
|
||||||
),
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -8,21 +8,40 @@ import django.db.models.deletion
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0036_custominvoice_remark")]
|
||||||
('cotisations', '0036_custominvoice_remark'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='CostEstimate',
|
name="CostEstimate",
|
||||||
fields=[
|
fields=[
|
||||||
('custominvoice_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='cotisations.CustomInvoice')),
|
(
|
||||||
('validity', models.DurationField(verbose_name='Period of validity')),
|
"custominvoice_ptr",
|
||||||
('final_invoice', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='origin_cost_estimate', to='cotisations.CustomInvoice')),
|
models.OneToOneField(
|
||||||
|
auto_created=True,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
parent_link=True,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
to="cotisations.CustomInvoice",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("validity", models.DurationField(verbose_name="Period of validity")),
|
||||||
|
(
|
||||||
|
"final_invoice",
|
||||||
|
models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="origin_cost_estimate",
|
||||||
|
to="cotisations.CustomInvoice",
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'permissions': (('view_costestimate', 'Can view a cost estimate object'),),
|
"permissions": (
|
||||||
|
("view_costestimate", "Can view a cost estimate object"),
|
||||||
|
)
|
||||||
},
|
},
|
||||||
bases=('cotisations.custominvoice',),
|
bases=("cotisations.custominvoice",),
|
||||||
),
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -8,24 +8,30 @@ import django.db.models.deletion
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("cotisations", "0037_costestimate")]
|
||||||
('cotisations', '0037_costestimate'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='costestimate',
|
model_name="costestimate",
|
||||||
name='final_invoice',
|
name="final_invoice",
|
||||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='origin_cost_estimate', to='cotisations.CustomInvoice'),
|
field=models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.SET_NULL,
|
||||||
|
related_name="origin_cost_estimate",
|
||||||
|
to="cotisations.CustomInvoice",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='costestimate',
|
model_name="costestimate",
|
||||||
name='validity',
|
name="validity",
|
||||||
field=models.DurationField(help_text='DD HH:MM:SS', verbose_name='Period of validity'),
|
field=models.DurationField(
|
||||||
|
help_text="DD HH:MM:SS", verbose_name="Period of validity"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='custominvoice',
|
model_name="custominvoice",
|
||||||
name='paid',
|
name="paid",
|
||||||
field=models.BooleanField(default=False, verbose_name='Paid'),
|
field=models.BooleanField(default=False, verbose_name="Paid"),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
40
cotisations/migrations/0039_freepayment.py
Normal file
40
cotisations/migrations/0039_freepayment.py
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.11.23 on 2019-09-30 09:19
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import cotisations.payment_methods.mixins
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [("cotisations", "0038_auto_20181231_1657")]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
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",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
options={"verbose_name": "Free payment"},
|
||||||
|
bases=(cotisations.payment_methods.mixins.PaymentMethodMixin, models.Model),
|
||||||
|
)
|
||||||
|
]
|
34
cotisations/migrations/0040_auto_20191002_2335.py
Normal file
34
cotisations/migrations/0040_auto_20191002_2335.py
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.11.23 on 2019-10-02 21:35
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import django.core.validators
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
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)",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
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)",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
64
cotisations/migrations/0041_auto_20191103_2131.py
Normal file
64
cotisations/migrations/0041_auto_20191103_2131.py
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.11.23 on 2019-11-03 20:31
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
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",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
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",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
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",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
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",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
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",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
79
cotisations/migrations/0042_auto_20191120_0159.py
Normal file
79
cotisations/migrations/0042_auto_20191120_0159.py
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.11.23 on 2019-11-20 00:59
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('cotisations', '0041_auto_20191103_2131'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='chequepayment',
|
||||||
|
options={'verbose_name': 'cheque'},
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='balancepayment',
|
||||||
|
name='credit_balance_allowed',
|
||||||
|
field=models.BooleanField(default=False, verbose_name='allow user to credit their balance'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='balancepayment',
|
||||||
|
name='maximum_balance',
|
||||||
|
field=models.DecimalField(blank=True, decimal_places=2, default=50, help_text='The maximal amount of money allowed for the balance.', max_digits=5, null=True, verbose_name='maximum balance'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='balancepayment',
|
||||||
|
name='minimum_balance',
|
||||||
|
field=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 a negative amount.', max_digits=5, verbose_name='minimum balance'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='baseinvoice',
|
||||||
|
name='date',
|
||||||
|
field=models.DateTimeField(auto_now_add=True, verbose_name='date'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='comnpaypayment',
|
||||||
|
name='minimum_payment',
|
||||||
|
field=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'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='comnpaypayment',
|
||||||
|
name='production',
|
||||||
|
field=models.BooleanField(default=True, verbose_name='production mode enabled (production URL, instead of homologation)'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
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='address',
|
||||||
|
field=models.CharField(max_length=255, verbose_name='address'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='custominvoice',
|
||||||
|
name='paid',
|
||||||
|
field=models.BooleanField(default=False, verbose_name='paid'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='custominvoice',
|
||||||
|
name='payment',
|
||||||
|
field=models.CharField(max_length=255, verbose_name='payment type'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='custominvoice',
|
||||||
|
name='recipient',
|
||||||
|
field=models.CharField(max_length=255, verbose_name='recipient'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='custominvoice',
|
||||||
|
name='remark',
|
||||||
|
field=models.TextField(blank=True, null=True, verbose_name='remark'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -3,7 +3,7 @@
|
||||||
# quelques clics.
|
# quelques clics.
|
||||||
#
|
#
|
||||||
# Copyright © 2017 Gabriel Détraz
|
# Copyright © 2017 Gabriel Détraz
|
||||||
# Copyright © 2017 Goulven Kermarec
|
# Copyright © 2017 Lara Kermarec
|
||||||
# Copyright © 2017 Augustin Lemesle
|
# Copyright © 2017 Augustin Lemesle
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -19,4 +19,3 @@
|
||||||
# You should have received a copy of the GNU General Public License along
|
# You should have received a copy of the GNU General Public License along
|
||||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -127,11 +127,6 @@ method to your model, where `form` is an instance of
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
from . import comnpay, cheque, balance, note_kfet, urls
|
from . import comnpay, cheque, balance, note_kfet, free, urls
|
||||||
|
|
||||||
PAYMENT_METHODS = [
|
PAYMENT_METHODS = [comnpay, cheque, balance, note_kfet, free]
|
||||||
comnpay,
|
|
||||||
cheque,
|
|
||||||
balance,
|
|
||||||
note_kfet
|
|
||||||
]
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
This module contains a method to pay online using user balance.
|
This module contains a method to pay online using user balance.
|
||||||
"""
|
"""
|
||||||
from . import models
|
from . import models
|
||||||
|
|
||||||
NAME = "BALANCE"
|
NAME = "BALANCE"
|
||||||
|
|
||||||
PaymentMethod = models.BalancePayment
|
PaymentMethod = models.BalancePayment
|
||||||
|
|
|
@ -40,21 +40,21 @@ class BalancePayment(PaymentMethodMixin, models.Model):
|
||||||
payment = models.OneToOneField(
|
payment = models.OneToOneField(
|
||||||
Paiement,
|
Paiement,
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
related_name='payment_method',
|
related_name="payment_method_balance",
|
||||||
editable=False
|
editable=False,
|
||||||
)
|
)
|
||||||
minimum_balance = models.DecimalField(
|
minimum_balance = models.DecimalField(
|
||||||
verbose_name=_("Minimum balance"),
|
verbose_name=_("minimum balance"),
|
||||||
help_text=_("The minimal amount of money allowed for the balance"
|
help_text=_(
|
||||||
" at the end of a payment. You can specify negative "
|
"The minimal amount of money allowed for the balance at the end"
|
||||||
"amount."
|
" of a payment. You can specify a negative amount."
|
||||||
),
|
),
|
||||||
max_digits=5,
|
max_digits=5,
|
||||||
decimal_places=2,
|
decimal_places=2,
|
||||||
default=0,
|
default=0,
|
||||||
)
|
)
|
||||||
maximum_balance = models.DecimalField(
|
maximum_balance = models.DecimalField(
|
||||||
verbose_name=_("Maximum balance"),
|
verbose_name=_("maximum balance"),
|
||||||
help_text=_("The maximal amount of money allowed for the balance."),
|
help_text=_("The maximal amount of money allowed for the balance."),
|
||||||
max_digits=5,
|
max_digits=5,
|
||||||
decimal_places=2,
|
decimal_places=2,
|
||||||
|
@ -63,8 +63,7 @@ class BalancePayment(PaymentMethodMixin, models.Model):
|
||||||
null=True,
|
null=True,
|
||||||
)
|
)
|
||||||
credit_balance_allowed = models.BooleanField(
|
credit_balance_allowed = models.BooleanField(
|
||||||
verbose_name=_("Allow user to credit their balance"),
|
verbose_name=_("allow user to credit their balance"), default=False
|
||||||
default=False,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def end_payment(self, invoice, request):
|
def end_payment(self, invoice, request):
|
||||||
|
@ -74,27 +73,17 @@ class BalancePayment(PaymentMethodMixin, models.Model):
|
||||||
user = invoice.user
|
user = invoice.user
|
||||||
total_price = invoice.prix_total()
|
total_price = invoice.prix_total()
|
||||||
if user.solde - total_price < self.minimum_balance:
|
if user.solde - total_price < self.minimum_balance:
|
||||||
messages.error(
|
messages.error(request, _("Your balance is too low for this operation."))
|
||||||
request,
|
return redirect(reverse("users:profil", kwargs={"userid": user.id}))
|
||||||
_("Your balance is too low for this operation.")
|
return invoice.paiement.end_payment(invoice, request, use_payment_method=False)
|
||||||
)
|
|
||||||
return redirect(reverse(
|
|
||||||
'users:profil',
|
|
||||||
kwargs={'userid': user.id}
|
|
||||||
))
|
|
||||||
return invoice.paiement.end_payment(
|
|
||||||
invoice,
|
|
||||||
request,
|
|
||||||
use_payment_method=False
|
|
||||||
)
|
|
||||||
|
|
||||||
def valid_form(self, form):
|
def valid_form(self, form):
|
||||||
"""Checks that there is not already a balance payment method."""
|
"""Checks that there is not already a balance payment method."""
|
||||||
p = Paiement.objects.filter(is_balance=True)
|
p = Paiement.objects.filter(is_balance=True)
|
||||||
if len(p) > 0:
|
if len(p) > 0:
|
||||||
form.add_error(
|
form.add_error(
|
||||||
'payment_method',
|
"payment_method",
|
||||||
_("There is already a payment method for user balance.")
|
_("There is already a payment method for user balance."),
|
||||||
)
|
)
|
||||||
|
|
||||||
def alter_payment(self, payment):
|
def alter_payment(self, payment):
|
||||||
|
@ -107,12 +96,11 @@ class BalancePayment(PaymentMethodMixin, models.Model):
|
||||||
"""
|
"""
|
||||||
return (
|
return (
|
||||||
user.solde - price >= self.minimum_balance,
|
user.solde - price >= self.minimum_balance,
|
||||||
_("Your balance is too low for this operation.")
|
_("Your balance is too low for this operation."),
|
||||||
)
|
)
|
||||||
|
|
||||||
def can_credit_balance(self, user_request):
|
def can_credit_balance(self, user_request):
|
||||||
return (
|
return (
|
||||||
len(Paiement.find_allowed_payments(user_request)
|
len(Paiement.find_allowed_payments(user_request).exclude(is_balance=True))
|
||||||
.exclude(is_balance=True)) > 0
|
> 0
|
||||||
) and self.credit_balance_allowed
|
) and self.credit_balance_allowed
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
This module contains a method to pay online using cheque.
|
This module contains a method to pay online using cheque.
|
||||||
"""
|
"""
|
||||||
from . import models, urls, views
|
from . import models, urls, views
|
||||||
|
|
||||||
NAME = "CHEQUE"
|
NAME = "CHEQUE"
|
||||||
|
|
||||||
PaymentMethod = models.ChequePayment
|
PaymentMethod = models.ChequePayment
|
||||||
|
|
|
@ -26,6 +26,7 @@ from cotisations.models import Facture as Invoice
|
||||||
|
|
||||||
class InvoiceForm(FormRevMixin, forms.ModelForm):
|
class InvoiceForm(FormRevMixin, forms.ModelForm):
|
||||||
"""A simple form to get the bank a the cheque number."""
|
"""A simple form to get the bank a the cheque number."""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Invoice
|
model = Invoice
|
||||||
fields = ['banque', 'cheque']
|
fields = ["banque", "cheque"]
|
||||||
|
|
|
@ -33,21 +33,19 @@ class ChequePayment(PaymentMethodMixin, models.Model):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("Cheque")
|
verbose_name = _("cheque")
|
||||||
|
|
||||||
payment = models.OneToOneField(
|
payment = models.OneToOneField(
|
||||||
Paiement,
|
Paiement,
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
related_name='payment_method',
|
related_name="payment_method_cheque",
|
||||||
editable=False
|
editable=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
def end_payment(self, invoice, request):
|
def end_payment(self, invoice, request):
|
||||||
"""Invalidates the invoice then redirect the user towards a view asking
|
"""Invalidates the invoice then redirect the user towards a view asking
|
||||||
for informations to add to the invoice before validating it.
|
for informations to add to the invoice before validating it.
|
||||||
"""
|
"""
|
||||||
return redirect(reverse(
|
return redirect(
|
||||||
'cotisations:cheque:validate',
|
reverse("cotisations:cheque:validate", kwargs={"invoice_pk": invoice.pk})
|
||||||
kwargs={'invoice_pk': invoice.pk}
|
)
|
||||||
))
|
|
||||||
|
|
||||||
|
|
|
@ -21,10 +21,4 @@
|
||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [url(r"^validate/(?P<invoice_pk>[0-9]+)$", views.cheque, name="validate")]
|
||||||
url(
|
|
||||||
r'^validate/(?P<invoice_pk>[0-9]+)$',
|
|
||||||
views.cheque,
|
|
||||||
name='validate'
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
|
@ -42,29 +42,17 @@ def cheque(request, invoice_pk):
|
||||||
invoice = get_object_or_404(Invoice, pk=invoice_pk)
|
invoice = get_object_or_404(Invoice, pk=invoice_pk)
|
||||||
payment_method = find_payment_method(invoice.paiement)
|
payment_method = find_payment_method(invoice.paiement)
|
||||||
if invoice.valid or not isinstance(payment_method, ChequePayment):
|
if invoice.valid or not isinstance(payment_method, ChequePayment):
|
||||||
messages.error(
|
messages.error(request, _("You can't pay this invoice with a cheque."))
|
||||||
request,
|
return redirect(reverse("users:profil", kwargs={"userid": request.user.pk}))
|
||||||
_("You can't pay this invoice with a cheque.")
|
|
||||||
)
|
|
||||||
return redirect(reverse(
|
|
||||||
'users:profil',
|
|
||||||
kwargs={'userid': request.user.pk}
|
|
||||||
))
|
|
||||||
form = InvoiceForm(request.POST or None, instance=invoice)
|
form = InvoiceForm(request.POST or None, instance=invoice)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.instance.valid = True
|
form.instance.valid = True
|
||||||
form.save()
|
form.save()
|
||||||
return form.instance.paiement.end_payment(
|
return form.instance.paiement.end_payment(
|
||||||
form.instance,
|
form.instance, request, use_payment_method=False
|
||||||
request,
|
|
||||||
use_payment_method=False
|
|
||||||
)
|
)
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
'cotisations/payment.html',
|
"cotisations/payment.html",
|
||||||
{
|
{"form": form, "amount": invoice.prix_total()},
|
||||||
'form': form,
|
|
||||||
'amount': invoice.prix_total()
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -22,5 +22,6 @@
|
||||||
This module contains a method to pay online using comnpay.
|
This module contains a method to pay online using comnpay.
|
||||||
"""
|
"""
|
||||||
from . import models, urls, views
|
from . import models, urls, views
|
||||||
|
|
||||||
NAME = "COMNPAY"
|
NAME = "COMNPAY"
|
||||||
PaymentMethod = models.ComnpayPayment
|
PaymentMethod = models.ComnpayPayment
|
||||||
|
|
|
@ -10,13 +10,21 @@ import hashlib
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
|
|
||||||
class Transaction():
|
class Transaction:
|
||||||
""" The class representing a transaction with all the functions
|
""" The class representing a transaction with all the functions
|
||||||
used during the negociation
|
used during the negociation
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, vad_number="", secret_key="", urlRetourOK="",
|
def __init__(
|
||||||
urlRetourNOK="", urlIPN="", source="", typeTr="D"):
|
self,
|
||||||
|
vad_number="",
|
||||||
|
secret_key="",
|
||||||
|
urlRetourOK="",
|
||||||
|
urlRetourNOK="",
|
||||||
|
urlIPN="",
|
||||||
|
source="",
|
||||||
|
typeTr="D",
|
||||||
|
):
|
||||||
self.vad_number = vad_number
|
self.vad_number = vad_number
|
||||||
self.secret_key = secret_key
|
self.secret_key = secret_key
|
||||||
self.urlRetourOK = urlRetourOK
|
self.urlRetourOK = urlRetourOK
|
||||||
|
@ -26,8 +34,7 @@ class Transaction():
|
||||||
self.typeTr = typeTr
|
self.typeTr = typeTr
|
||||||
self.idTransaction = ""
|
self.idTransaction = ""
|
||||||
|
|
||||||
def buildSecretHTML(self, produit="Produit", montant="0.00",
|
def buildSecretHTML(self, produit="Produit", montant="0.00", idTransaction=""):
|
||||||
idTransaction=""):
|
|
||||||
""" Build an HTML hidden form with the different parameters for the
|
""" Build an HTML hidden form with the different parameters for the
|
||||||
transaction
|
transaction
|
||||||
"""
|
"""
|
||||||
|
@ -43,30 +50,26 @@ class Transaction():
|
||||||
idTPE=self.vad_number,
|
idTPE=self.vad_number,
|
||||||
idTransaction=self.idTransaction,
|
idTransaction=self.idTransaction,
|
||||||
devise="EUR",
|
devise="EUR",
|
||||||
lang='fr',
|
lang="fr",
|
||||||
nom_produit=produit,
|
nom_produit=produit,
|
||||||
source=self.source,
|
source=self.source,
|
||||||
urlRetourOK=self.urlRetourOK,
|
urlRetourOK=self.urlRetourOK,
|
||||||
urlRetourNOK=self.urlRetourNOK,
|
urlRetourNOK=self.urlRetourNOK,
|
||||||
typeTr=str(self.typeTr)
|
typeTr=str(self.typeTr),
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.urlIPN != "":
|
if self.urlIPN != "":
|
||||||
array_tpe['urlIPN'] = self.urlIPN
|
array_tpe["urlIPN"] = self.urlIPN
|
||||||
|
|
||||||
array_tpe['key'] = self.secret_key
|
array_tpe["key"] = self.secret_key
|
||||||
strWithKey = base64.b64encode(bytes(
|
strWithKey = base64.b64encode(bytes("|".join(array_tpe.values()), "utf-8"))
|
||||||
'|'.join(array_tpe.values()),
|
|
||||||
'utf-8'
|
|
||||||
))
|
|
||||||
del array_tpe["key"]
|
del array_tpe["key"]
|
||||||
array_tpe['sec'] = hashlib.sha512(strWithKey).hexdigest()
|
array_tpe["sec"] = hashlib.sha512(strWithKey).hexdigest()
|
||||||
|
|
||||||
ret = ""
|
ret = ""
|
||||||
for key in array_tpe:
|
for key in array_tpe:
|
||||||
ret += '<input type="hidden" name="{k}" value="{v}"/>'.format(
|
ret += '<input type="hidden" name="{k}" value="{v}"/>'.format(
|
||||||
k=key,
|
k=key, v=array_tpe[key]
|
||||||
v=array_tpe[key]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
@ -75,12 +78,13 @@ class Transaction():
|
||||||
def validSec(values, secret_key):
|
def validSec(values, secret_key):
|
||||||
""" Check if the secret value is correct """
|
""" Check if the secret value is correct """
|
||||||
if "sec" in values:
|
if "sec" in values:
|
||||||
sec = values['sec']
|
sec = values["sec"]
|
||||||
del values["sec"]
|
del values["sec"]
|
||||||
strWithKey = hashlib.sha512(base64.b64encode(bytes(
|
strWithKey = hashlib.sha512(
|
||||||
'|'.join(values.values()) + "|" + secret_key,
|
base64.b64encode(
|
||||||
'utf-8'
|
bytes("|".join(values.values()) + "|" + secret_key, "utf-8")
|
||||||
))).hexdigest()
|
)
|
||||||
|
).hexdigest()
|
||||||
return strWithKey.upper() == sec.upper()
|
return strWithKey.upper() == sec.upper()
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -41,39 +41,37 @@ class ComnpayPayment(PaymentMethodMixin, models.Model):
|
||||||
payment = models.OneToOneField(
|
payment = models.OneToOneField(
|
||||||
Paiement,
|
Paiement,
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
related_name='payment_method',
|
related_name="payment_method_comnpay",
|
||||||
editable=False
|
editable=False,
|
||||||
)
|
)
|
||||||
payment_credential = models.CharField(
|
payment_credential = models.CharField(
|
||||||
max_length=255,
|
max_length=255, default="", blank=True, verbose_name=_("ComNpay VAT Number")
|
||||||
default='',
|
|
||||||
blank=True,
|
|
||||||
verbose_name=_("ComNpay VAT Number"),
|
|
||||||
)
|
)
|
||||||
payment_pass = AESEncryptedField(
|
payment_pass = AESEncryptedField(
|
||||||
max_length=255,
|
max_length=255, null=True, blank=True, verbose_name=_("ComNpay secret key")
|
||||||
null=True,
|
|
||||||
blank=True,
|
|
||||||
verbose_name=_("ComNpay secret key"),
|
|
||||||
)
|
)
|
||||||
minimum_payment = models.DecimalField(
|
minimum_payment = models.DecimalField(
|
||||||
verbose_name=_("Minimum payment"),
|
verbose_name=_("minimum payment"),
|
||||||
help_text=_("The minimal amount of money you have to use when paying"
|
help_text=_(
|
||||||
" with ComNpay"),
|
"The minimal amount of money you have to use when paying with"
|
||||||
|
" ComNpay."
|
||||||
|
),
|
||||||
max_digits=5,
|
max_digits=5,
|
||||||
decimal_places=2,
|
decimal_places=2,
|
||||||
default=1,
|
default=1,
|
||||||
)
|
)
|
||||||
production = models.BooleanField(
|
production = models.BooleanField(
|
||||||
default=True,
|
default=True,
|
||||||
verbose_name=_("Production mode enabled (production URL, instead of homologation)"),
|
verbose_name=_(
|
||||||
|
"production mode enabled (production URL, instead of homologation)"
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
def return_url_comnpay(self):
|
def return_url_comnpay(self):
|
||||||
if self.production:
|
if self.production:
|
||||||
return 'https://secure.comnpay.com'
|
return "https://secure.comnpay.com"
|
||||||
else:
|
else:
|
||||||
return 'https://secure.homologation.comnpay.com'
|
return "https://secure.homologation.comnpay.com"
|
||||||
|
|
||||||
def end_payment(self, invoice, request):
|
def end_payment(self, invoice, request):
|
||||||
"""
|
"""
|
||||||
|
@ -85,32 +83,36 @@ class ComnpayPayment(PaymentMethodMixin, models.Model):
|
||||||
p = Transaction(
|
p = Transaction(
|
||||||
str(self.payment_credential),
|
str(self.payment_credential),
|
||||||
str(self.payment_pass),
|
str(self.payment_pass),
|
||||||
'https://' + host + reverse(
|
"https://"
|
||||||
'cotisations:comnpay:accept_payment',
|
+ host
|
||||||
kwargs={'factureid': invoice.id}
|
+ reverse(
|
||||||
|
"cotisations:comnpay:accept_payment", kwargs={"factureid": invoice.id}
|
||||||
),
|
),
|
||||||
'https://' + host + reverse('cotisations:comnpay:refuse_payment'),
|
"https://" + host + reverse("cotisations:comnpay:refuse_payment"),
|
||||||
'https://' + host + reverse('cotisations:comnpay:ipn'),
|
"https://" + host + reverse("cotisations:comnpay:ipn"),
|
||||||
"",
|
"",
|
||||||
"D"
|
"D",
|
||||||
)
|
)
|
||||||
|
|
||||||
r = {
|
r = {
|
||||||
'action': self.return_url_comnpay(),
|
"action": self.return_url_comnpay(),
|
||||||
'method': 'POST',
|
"method": "POST",
|
||||||
'content': p.buildSecretHTML(
|
"content": p.buildSecretHTML(
|
||||||
_("Pay invoice number ")+str(invoice.id),
|
_("Pay invoice number ") + str(invoice.id),
|
||||||
invoice.prix_total(),
|
invoice.prix_total(),
|
||||||
idTransaction=str(invoice.id)
|
idTransaction=str(invoice.id),
|
||||||
),
|
),
|
||||||
'amount': invoice.prix_total(),
|
"amount": invoice.prix_total(),
|
||||||
}
|
}
|
||||||
return render(request, 'cotisations/payment.html', r)
|
return render(request, "cotisations/payment.html", r)
|
||||||
|
|
||||||
def check_price(self, price, *args, **kwargs):
|
def check_price(self, price, *args, **kwargs):
|
||||||
"""Checks that the price meets the requirement to be paid with ComNpay.
|
"""Checks that the price meets the requirement to be paid with ComNpay.
|
||||||
"""
|
"""
|
||||||
return ((price >= self.minimum_payment),
|
return (
|
||||||
_("In order to pay your invoice with ComNpay, the price must"
|
(price >= self.minimum_payment),
|
||||||
" be greater than {} €.").format(self.minimum_payment))
|
_(
|
||||||
|
"In order to pay your invoice with ComNpay, the price must"
|
||||||
|
" be greater than {} €."
|
||||||
|
).format(self.minimum_payment),
|
||||||
|
)
|
||||||
|
|
|
@ -22,19 +22,7 @@ from django.conf.urls import url
|
||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(
|
url(r"^accept/(?P<factureid>[0-9]+)$", views.accept_payment, name="accept_payment"),
|
||||||
r'^accept/(?P<factureid>[0-9]+)$',
|
url(r"^refuse/$", views.refuse_payment, name="refuse_payment"),
|
||||||
views.accept_payment,
|
url(r"^ipn/$", views.ipn, name="ipn"),
|
||||||
name='accept_payment'
|
|
||||||
),
|
|
||||||
url(
|
|
||||||
r'^refuse/$',
|
|
||||||
views.refuse_payment,
|
|
||||||
name='refuse_payment'
|
|
||||||
),
|
|
||||||
url(
|
|
||||||
r'^ipn/$',
|
|
||||||
views.ipn,
|
|
||||||
name='ipn'
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -50,26 +50,24 @@ def accept_payment(request, factureid):
|
||||||
if invoice.valid:
|
if invoice.valid:
|
||||||
messages.success(
|
messages.success(
|
||||||
request,
|
request,
|
||||||
_("The payment of %(amount)s € was accepted.") % {
|
_("The payment of %(amount)s € was accepted.")
|
||||||
'amount': invoice.prix_total()
|
% {"amount": invoice.prix_total()},
|
||||||
}
|
|
||||||
)
|
)
|
||||||
# In case a cotisation was bought, inform the user, the
|
# In case a cotisation was bought, inform the user, the
|
||||||
# cotisation time has been extended too
|
# cotisation time has been extended too
|
||||||
if any(purchase.type_cotisation
|
if any(purchase.type_cotisation for purchase in invoice.vente_set.all()):
|
||||||
for purchase in invoice.vente_set.all()):
|
|
||||||
messages.success(
|
messages.success(
|
||||||
request,
|
request,
|
||||||
_("The subscription of %(member_name)s was extended to"
|
_(
|
||||||
" %(end_date)s.") % {
|
"The subscription of %(member_name)s was extended to"
|
||||||
'member_name': invoice.user.pseudo,
|
" %(end_date)s."
|
||||||
'end_date': invoice.user.end_adhesion()
|
)
|
||||||
}
|
% {
|
||||||
|
"member_name": invoice.user.pseudo,
|
||||||
|
"end_date": invoice.user.end_adhesion(),
|
||||||
|
},
|
||||||
)
|
)
|
||||||
return redirect(reverse(
|
return redirect(reverse("users:profil", kwargs={"userid": invoice.user.id}))
|
||||||
'users:profil',
|
|
||||||
kwargs={'userid': invoice.user.id}
|
|
||||||
))
|
|
||||||
|
|
||||||
|
|
||||||
@csrf_exempt
|
@csrf_exempt
|
||||||
|
@ -79,14 +77,8 @@ def refuse_payment(request):
|
||||||
The view where the user is redirected when a comnpay payment has been
|
The view where the user is redirected when a comnpay payment has been
|
||||||
refused.
|
refused.
|
||||||
"""
|
"""
|
||||||
messages.error(
|
messages.error(request, _("The payment was refused."))
|
||||||
request,
|
return redirect(reverse("users:profil", kwargs={"userid": request.user.id}))
|
||||||
_("The payment was refused.")
|
|
||||||
)
|
|
||||||
return redirect(reverse(
|
|
||||||
'users:profil',
|
|
||||||
kwargs={'userid': request.user.id}
|
|
||||||
))
|
|
||||||
|
|
||||||
|
|
||||||
@csrf_exempt
|
@csrf_exempt
|
||||||
|
@ -97,27 +89,26 @@ def ipn(request):
|
||||||
Comnpay with 400 response if not or with a 200 response if yes.
|
Comnpay with 400 response if not or with a 200 response if yes.
|
||||||
"""
|
"""
|
||||||
p = Transaction()
|
p = Transaction()
|
||||||
order = ('idTpe', 'idTransaction', 'montant', 'result', 'sec', )
|
order = ("idTpe", "idTransaction", "montant", "result", "sec")
|
||||||
try:
|
try:
|
||||||
data = OrderedDict([(f, request.POST[f]) for f in order])
|
data = OrderedDict([(f, request.POST[f]) for f in order])
|
||||||
except MultiValueDictKeyError:
|
except MultiValueDictKeyError:
|
||||||
return HttpResponseBadRequest("HTTP/1.1 400 Bad Request")
|
return HttpResponseBadRequest("HTTP/1.1 400 Bad Request")
|
||||||
|
|
||||||
idTransaction = request.POST['idTransaction']
|
idTransaction = request.POST["idTransaction"]
|
||||||
try:
|
try:
|
||||||
factureid = int(idTransaction)
|
factureid = int(idTransaction)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return HttpResponseBadRequest("HTTP/1.1 400 Bad Request")
|
return HttpResponseBadRequest("HTTP/1.1 400 Bad Request")
|
||||||
|
|
||||||
facture = get_object_or_404(Facture, id=factureid)
|
facture = get_object_or_404(Facture, id=factureid)
|
||||||
payment_method = get_object_or_404(
|
payment_method = get_object_or_404(ComnpayPayment, payment=facture.paiement)
|
||||||
ComnpayPayment, payment=facture.paiement)
|
|
||||||
|
|
||||||
if not p.validSec(data, payment_method.payment_pass):
|
if not p.validSec(data, payment_method.payment_pass):
|
||||||
return HttpResponseBadRequest("HTTP/1.1 400 Bad Request")
|
return HttpResponseBadRequest("HTTP/1.1 400 Bad Request")
|
||||||
|
|
||||||
result = True if (request.POST['result'] == 'OK') else False
|
result = True if (request.POST["result"] == "OK") else False
|
||||||
idTpe = request.POST['idTpe']
|
idTpe = request.POST["idTpe"]
|
||||||
|
|
||||||
# Checking that the payment is actually for us.
|
# Checking that the payment is actually for us.
|
||||||
if not idTpe == payment_method.payment_credential:
|
if not idTpe == payment_method.payment_credential:
|
||||||
|
@ -136,4 +127,3 @@ def ipn(request):
|
||||||
# Everything worked we send a reponse to Comnpay indicating that
|
# Everything worked we send a reponse to Comnpay indicating that
|
||||||
# it's ok for them to proceed
|
# it's ok for them to proceed
|
||||||
return HttpResponse("HTTP/1.0 200 OK")
|
return HttpResponse("HTTP/1.0 200 OK")
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
from . import PAYMENT_METHODS
|
from . import PAYMENT_METHODS
|
||||||
from cotisations.utils import find_payment_method
|
from cotisations.utils import find_payment_method
|
||||||
|
|
||||||
|
|
||||||
def payment_method_factory(payment, *args, creation=True, **kwargs):
|
def payment_method_factory(payment, *args, creation=True, **kwargs):
|
||||||
"""This function finds the right payment method form for a given payment.
|
"""This function finds the right payment method form for a given payment.
|
||||||
|
|
||||||
|
@ -40,12 +41,10 @@ def payment_method_factory(payment, *args, creation=True, **kwargs):
|
||||||
Returns:
|
Returns:
|
||||||
A form or None
|
A form or None
|
||||||
"""
|
"""
|
||||||
payment_method = kwargs.pop('instance', find_payment_method(payment))
|
payment_method = kwargs.pop("instance", find_payment_method(payment))
|
||||||
if payment_method is not None:
|
if payment_method is not None:
|
||||||
return forms.modelform_factory(type(payment_method), fields='__all__')(
|
return forms.modelform_factory(type(payment_method), fields="__all__")(
|
||||||
*args,
|
*args, instance=payment_method, **kwargs
|
||||||
instance=payment_method,
|
|
||||||
**kwargs
|
|
||||||
)
|
)
|
||||||
elif creation:
|
elif creation:
|
||||||
return PaymentMethodForm(*args, **kwargs)
|
return PaymentMethodForm(*args, **kwargs)
|
||||||
|
@ -58,23 +57,24 @@ class PaymentMethodForm(forms.Form):
|
||||||
|
|
||||||
payment_method = forms.ChoiceField(
|
payment_method = forms.ChoiceField(
|
||||||
label=_("Special payment method"),
|
label=_("Special payment method"),
|
||||||
help_text=_("Warning: you will not be able to change the payment "
|
help_text=_(
|
||||||
"method later. But you will be allowed to edit the other "
|
"Warning: you will not be able to change the payment"
|
||||||
"options."
|
" method later. But you will be allowed to edit the other"
|
||||||
|
" options."
|
||||||
),
|
),
|
||||||
required=False
|
required=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(PaymentMethodForm, self).__init__(*args, **kwargs)
|
super(PaymentMethodForm, self).__init__(*args, **kwargs)
|
||||||
prefix = kwargs.get('prefix', None)
|
prefix = kwargs.get("prefix", None)
|
||||||
self.fields['payment_method'].choices = [(i,p.NAME) for (i,p) in enumerate(PAYMENT_METHODS)]
|
self.fields["payment_method"].choices = [
|
||||||
self.fields['payment_method'].choices.insert(0, ('', _('no')))
|
(i, p.NAME) for (i, p) in enumerate(PAYMENT_METHODS)
|
||||||
self.fields['payment_method'].widget.attrs = {
|
]
|
||||||
'id': 'paymentMethodSelect'
|
self.fields["payment_method"].choices.insert(0, ("", _("No")))
|
||||||
}
|
self.fields["payment_method"].widget.attrs = {"id": "paymentMethodSelect"}
|
||||||
self.templates = [
|
self.templates = [
|
||||||
forms.modelform_factory(p.PaymentMethod, fields='__all__')(prefix=prefix)
|
forms.modelform_factory(p.PaymentMethod, fields="__all__")(prefix=prefix)
|
||||||
for p in PAYMENT_METHODS
|
for p in PAYMENT_METHODS
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -84,29 +84,29 @@ class PaymentMethodForm(forms.Form):
|
||||||
found. Tries to call `payment_method.valid_form` if it exists.
|
found. Tries to call `payment_method.valid_form` if it exists.
|
||||||
"""
|
"""
|
||||||
super(PaymentMethodForm, self).clean()
|
super(PaymentMethodForm, self).clean()
|
||||||
choice = self.cleaned_data['payment_method']
|
choice = self.cleaned_data["payment_method"]
|
||||||
if choice=='':
|
if choice == "":
|
||||||
return
|
return
|
||||||
choice = int(choice)
|
choice = int(choice)
|
||||||
model = PAYMENT_METHODS[choice].PaymentMethod
|
model = PAYMENT_METHODS[choice].PaymentMethod
|
||||||
form = forms.modelform_factory(model, fields='__all__')(self.data, prefix=self.prefix)
|
form = forms.modelform_factory(model, fields="__all__")(
|
||||||
|
self.data, prefix=self.prefix
|
||||||
|
)
|
||||||
self.payment_method = form.save(commit=False)
|
self.payment_method = form.save(commit=False)
|
||||||
if hasattr(self.payment_method, 'valid_form'):
|
if hasattr(self.payment_method, "valid_form"):
|
||||||
self.payment_method.valid_form(self)
|
self.payment_method.valid_form(self)
|
||||||
return self.cleaned_data
|
return self.cleaned_data
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def save(self, payment, *args, **kwargs):
|
def save(self, payment, *args, **kwargs):
|
||||||
"""Saves the payment method.
|
"""Saves the payment method.
|
||||||
|
|
||||||
Tries to call `payment_method.alter_payment` if it exists.
|
Tries to call `payment_method.alter_payment` if it exists.
|
||||||
"""
|
"""
|
||||||
commit = kwargs.pop('commit', True)
|
commit = kwargs.pop("commit", True)
|
||||||
if not hasattr(self, 'payment_method'):
|
if not hasattr(self, "payment_method"):
|
||||||
return None
|
return None
|
||||||
self.payment_method.payment = payment
|
self.payment_method.payment = payment
|
||||||
if hasattr(self.payment_method, 'alter_payment'):
|
if hasattr(self.payment_method, "alter_payment"):
|
||||||
self.payment_method.alter_payment(payment)
|
self.payment_method.alter_payment(payment)
|
||||||
if commit:
|
if commit:
|
||||||
payment.save()
|
payment.save()
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
|
# -*- mode: python; coding: utf-8 -*-
|
||||||
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
|
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
|
||||||
# se veut agnostique au réseau considéré, de manière à être installable en
|
# se veut agnostique au réseau considéré, de manière à être installable en
|
||||||
# quelques clics.
|
# quelques clics.
|
||||||
#
|
#
|
||||||
# Copyright © 2017 Gabriel Détraz
|
# Copyright © 2019 Hugo Levy-Falk
|
||||||
# Copyright © 2017 Goulven Kermarec
|
|
||||||
# Copyright © 2017 Augustin Lemesle
|
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -19,10 +18,11 @@
|
||||||
# You should have received a copy of the GNU General Public License along
|
# You should have received a copy of the GNU General Public License along
|
||||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
"""cotisations.tests
|
|
||||||
The tests for the Cotisations module.
|
|
||||||
"""
|
"""
|
||||||
|
This module contains a method to pay online using user balance.
|
||||||
|
"""
|
||||||
|
from . import models
|
||||||
|
|
||||||
# from django.test import TestCase
|
NAME = "FREE"
|
||||||
|
|
||||||
# Create your tests here.
|
PaymentMethod = models.FreePayment
|
54
cotisations/payment_methods/free/models.py
Normal file
54
cotisations/payment_methods/free/models.py
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
# -*- mode: python; coding: utf-8 -*-
|
||||||
|
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
|
||||||
|
# se veut agnostique au réseau considéré, de manière à être installable en
|
||||||
|
# quelques clics.
|
||||||
|
#
|
||||||
|
# Copyright © 2018 Hugo Levy-Falk
|
||||||
|
#
|
||||||
|
# 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
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
from django.db import models
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
from django.contrib import messages
|
||||||
|
|
||||||
|
|
||||||
|
from cotisations.models import Paiement
|
||||||
|
from cotisations.payment_methods.mixins import PaymentMethodMixin
|
||||||
|
|
||||||
|
|
||||||
|
class FreePayment(PaymentMethodMixin, models.Model):
|
||||||
|
"""
|
||||||
|
The model allowing you to bypass payment if the invoice is free.
|
||||||
|
"""
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = _("Free payment")
|
||||||
|
|
||||||
|
payment = models.OneToOneField(
|
||||||
|
Paiement,
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
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)
|
||||||
|
|
||||||
|
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 can't pay this invoice for free."))
|
|
@ -29,5 +29,4 @@ class PaymentMethodMixin:
|
||||||
|
|
||||||
Must return a HttpResponse-like object.
|
Must return a HttpResponse-like object.
|
||||||
"""
|
"""
|
||||||
return self.payment.end_payment(
|
return self.payment.end_payment(invoice, request, use_payment_method=False)
|
||||||
invoice, request, use_payment_method=False)
|
|
||||||
|
|
|
@ -22,5 +22,6 @@
|
||||||
This module contains a method to pay online using comnpay.
|
This module contains a method to pay online using comnpay.
|
||||||
"""
|
"""
|
||||||
from . import models, urls
|
from . import models, urls
|
||||||
|
|
||||||
NAME = "NOTE"
|
NAME = "NOTE"
|
||||||
PaymentMethod = models.NotePayment
|
PaymentMethod = models.NotePayment
|
||||||
|
|
|
@ -24,15 +24,11 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from cotisations.utils import find_payment_method
|
from cotisations.utils import find_payment_method
|
||||||
|
|
||||||
|
|
||||||
class NoteCredentialForm(forms.Form):
|
class NoteCredentialForm(forms.Form):
|
||||||
"""A special form to get credential to connect to a NoteKfet2015 server throught his API
|
"""A special form to get credential to connect to a NoteKfet2015 server throught his API
|
||||||
object.
|
object.
|
||||||
"""
|
"""
|
||||||
login = forms.CharField(
|
|
||||||
label=_("pseudo note")
|
login = forms.CharField(label=_("Username"))
|
||||||
)
|
password = forms.CharField(label=_("Password"), widget=forms.PasswordInput)
|
||||||
password = forms.CharField(
|
|
||||||
label=_("Password"),
|
|
||||||
widget=forms.PasswordInput
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
|
@ -41,25 +41,17 @@ class NotePayment(PaymentMethodMixin, models.Model):
|
||||||
|
|
||||||
payment = models.OneToOneField(
|
payment = models.OneToOneField(
|
||||||
Paiement,
|
Paiement,
|
||||||
on_delete = models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
related_name = 'payment_method',
|
related_name="payment_method_note",
|
||||||
editable = False
|
editable=False,
|
||||||
)
|
|
||||||
server = models.CharField(
|
|
||||||
max_length=255,
|
|
||||||
verbose_name=_("server")
|
|
||||||
)
|
|
||||||
port = models.PositiveIntegerField(
|
|
||||||
blank = True,
|
|
||||||
null = True
|
|
||||||
)
|
|
||||||
id_note = models.PositiveIntegerField(
|
|
||||||
blank = True,
|
|
||||||
null = True
|
|
||||||
)
|
)
|
||||||
|
server = models.CharField(max_length=255, verbose_name=_("server"))
|
||||||
|
port = models.PositiveIntegerField(blank=True, null=True)
|
||||||
|
id_note = models.PositiveIntegerField(blank=True, null=True)
|
||||||
|
|
||||||
def end_payment(self, invoice, request):
|
def end_payment(self, invoice, request):
|
||||||
return redirect(reverse(
|
return redirect(
|
||||||
'cotisations:note_kfet:note_payment',
|
reverse(
|
||||||
kwargs={'factureid': invoice.id}
|
"cotisations:note_kfet:note_payment", kwargs={"factureid": invoice.id}
|
||||||
))
|
)
|
||||||
|
)
|
||||||
|
|
|
@ -12,13 +12,14 @@ import traceback
|
||||||
|
|
||||||
|
|
||||||
def get_response(socket):
|
def get_response(socket):
|
||||||
length_str = b''
|
length_str = b""
|
||||||
char = socket.recv(1)
|
char = socket.recv(1)
|
||||||
while char != b'\n':
|
while char != b"\n":
|
||||||
length_str += char
|
length_str += char
|
||||||
char = socket.recv(1)
|
char = socket.recv(1)
|
||||||
total = int(length_str)
|
total = int(length_str)
|
||||||
return json.loads(socket.recv(total).decode('utf-8'))
|
return json.loads(socket.recv(total).decode("utf-8"))
|
||||||
|
|
||||||
|
|
||||||
def connect(server, port):
|
def connect(server, port):
|
||||||
sock = socket.socket()
|
sock = socket.socket()
|
||||||
|
@ -35,7 +36,8 @@ def connect(server, port):
|
||||||
return (False, sock, "Serveur indisponible")
|
return (False, sock, "Serveur indisponible")
|
||||||
return (True, sock, "")
|
return (True, sock, "")
|
||||||
|
|
||||||
def login(server, port, username, password, masque = [[], [], True]):
|
|
||||||
|
def login(server, port, username, password, masque=[[], [], True]):
|
||||||
result, sock, err = connect(server, port)
|
result, sock, err = connect(server, port)
|
||||||
if not result:
|
if not result:
|
||||||
return (False, None, err)
|
return (False, None, err)
|
||||||
|
@ -43,7 +45,7 @@ def login(server, port, username, password, masque = [[], [], True]):
|
||||||
commande = ["login", [username, password, "bdd", masque]]
|
commande = ["login", [username, password, "bdd", masque]]
|
||||||
sock.send(json.dumps(commande).encode("utf-8"))
|
sock.send(json.dumps(commande).encode("utf-8"))
|
||||||
response = get_response(sock)
|
response = get_response(sock)
|
||||||
retcode = response['retcode']
|
retcode = response["retcode"]
|
||||||
if retcode == 0:
|
if retcode == 0:
|
||||||
return (True, sock, "")
|
return (True, sock, "")
|
||||||
elif retcode == 5:
|
elif retcode == 5:
|
||||||
|
@ -60,11 +62,28 @@ def don(sock, montant, id_note, facture):
|
||||||
Faire faire un don à l'id_note
|
Faire faire un don à l'id_note
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
sock.send(json.dumps(["dons", [[id_note], round(montant*100), "Facture : id=%s, designation=%s" % (facture.id, facture.name())]]).encode("utf-8"))
|
sock.send(
|
||||||
|
json.dumps(
|
||||||
|
[
|
||||||
|
"dons",
|
||||||
|
[
|
||||||
|
[id_note],
|
||||||
|
round(montant * 100),
|
||||||
|
"Facture : id=%s, designation=%s"
|
||||||
|
% (facture.id, facture.name()),
|
||||||
|
],
|
||||||
|
]
|
||||||
|
).encode("utf-8")
|
||||||
|
)
|
||||||
response = get_response(sock)
|
response = get_response(sock)
|
||||||
retcode = response['retcode']
|
retcode = response["retcode"]
|
||||||
transaction_retcode = response["msg"][0][0]
|
transaction_retcode = response["msg"][0][0]
|
||||||
if 0 < retcode < 100 or 200 <= retcode or 0 < transaction_retcode < 100 or 200 <= transaction_retcode:
|
if (
|
||||||
|
0 < retcode < 100
|
||||||
|
or 200 <= retcode
|
||||||
|
or 0 < transaction_retcode < 100
|
||||||
|
or 200 <= transaction_retcode
|
||||||
|
):
|
||||||
return (False, "Transaction échouée. (Solde trop négatif ?)")
|
return (False, "Transaction échouée. (Solde trop négatif ?)")
|
||||||
elif retcode == 0:
|
elif retcode == 0:
|
||||||
return (True, "")
|
return (True, "")
|
||||||
|
|
|
@ -23,8 +23,6 @@ from . import views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(
|
url(
|
||||||
r'^note_payment/(?P<factureid>[0-9]+)$',
|
r"^note_payment/(?P<factureid>[0-9]+)$", views.note_payment, name="note_payment"
|
||||||
views.note_payment,
|
)
|
||||||
name='note_payment'
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
# quelques clics.
|
# quelques clics.
|
||||||
#
|
#
|
||||||
# Copyright © 2018 Gabriel Detraz
|
# 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
|
# 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
|
# 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 cotisations.utils import find_payment_method
|
||||||
from .models import NotePayment
|
from .models import NotePayment
|
||||||
from re2o.views import form
|
from re2o.views import form
|
||||||
from re2o.acl import (
|
from re2o.acl import can_create, can_edit
|
||||||
can_create,
|
|
||||||
can_edit
|
|
||||||
)
|
|
||||||
from .note import login, don
|
from .note import login, don
|
||||||
from .forms import NoteCredentialForm
|
from .forms import NoteCredentialForm
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@can_edit(Facture)
|
@can_edit(Facture)
|
||||||
def note_payment(request, facture, factureid):
|
def note_payment(request, facture, factureid):
|
||||||
|
@ -58,40 +56,38 @@ def note_payment(request, facture, factureid):
|
||||||
payment_method = find_payment_method(facture.paiement)
|
payment_method = find_payment_method(facture.paiement)
|
||||||
if not payment_method or not isinstance(payment_method, NotePayment):
|
if not payment_method or not isinstance(payment_method, NotePayment):
|
||||||
messages.error(request, _("Unknown error."))
|
messages.error(request, _("Unknown error."))
|
||||||
return redirect(reverse(
|
return redirect(reverse("users:profil", kwargs={"userid": user.id}))
|
||||||
'users:profil',
|
|
||||||
kwargs={'userid': user.id}
|
|
||||||
))
|
|
||||||
noteform = NoteCredentialForm(request.POST or None)
|
noteform = NoteCredentialForm(request.POST or None)
|
||||||
if noteform.is_valid():
|
if noteform.is_valid():
|
||||||
pseudo = noteform.cleaned_data['login']
|
pseudo = noteform.cleaned_data["login"]
|
||||||
password = noteform.cleaned_data['password']
|
password = noteform.cleaned_data["password"]
|
||||||
result, sock, err = login(payment_method.server, payment_method.port, pseudo, password)
|
result, sock, err = login(
|
||||||
|
payment_method.server, payment_method.port, pseudo, password
|
||||||
|
)
|
||||||
if not result:
|
if not result:
|
||||||
messages.error(request, err)
|
messages.error(request, err)
|
||||||
return form(
|
return form(
|
||||||
{'form': noteform, 'amount': facture.prix_total()},
|
{"form": noteform, "amount": facture.prix_total()},
|
||||||
"cotisations/payment.html",
|
"cotisations/payment.html",
|
||||||
request
|
request,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
result, err = don(sock, facture.prix_total(), payment_method.id_note, facture)
|
result, err = don(
|
||||||
|
sock, facture.prix_total(), payment_method.id_note, facture
|
||||||
|
)
|
||||||
if not result:
|
if not result:
|
||||||
messages.error(request, err)
|
messages.error(request, err)
|
||||||
return form(
|
return form(
|
||||||
{'form': noteform, 'amount': facture.prix_total()},
|
{"form": noteform, "amount": facture.prix_total()},
|
||||||
"cotisations/payment.html",
|
"cotisations/payment.html",
|
||||||
request
|
request,
|
||||||
)
|
)
|
||||||
facture.valid = True
|
facture.valid = True
|
||||||
facture.save()
|
facture.save()
|
||||||
messages.success(request, _("The payment with note was done."))
|
messages.success(request, _("The payment with note was done."))
|
||||||
return redirect(reverse(
|
return redirect(reverse("users:profil", kwargs={"userid": user.id}))
|
||||||
'users:profil',
|
|
||||||
kwargs={'userid': user.id}
|
|
||||||
))
|
|
||||||
return form(
|
return form(
|
||||||
{'form': noteform, 'amount': facture.prix_total()},
|
{"form": noteform, "amount": facture.prix_total()},
|
||||||
"cotisations/payment.html",
|
"cotisations/payment.html",
|
||||||
request
|
request,
|
||||||
)
|
)
|
||||||
|
|
|
@ -22,7 +22,7 @@ from django.conf.urls import include, url
|
||||||
from . import comnpay, cheque, note_kfet
|
from . import comnpay, cheque, note_kfet
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^comnpay/', include(comnpay.urls, namespace='comnpay')),
|
url(r"^comnpay/", include(comnpay.urls, namespace="comnpay")),
|
||||||
url(r'^cheque/', include(cheque.urls, namespace='cheque')),
|
url(r"^cheque/", include(cheque.urls, namespace="cheque")),
|
||||||
url(r'^note_kfet/', include(note_kfet.urls, namespace='note_kfet')),
|
url(r"^note_kfet/", include(note_kfet.urls, namespace="note_kfet")),
|
||||||
]
|
]
|
||||||
|
|
|
@ -4,7 +4,7 @@ se veut agnostique au réseau considéré, de manière à être installable en
|
||||||
quelques clics.
|
quelques clics.
|
||||||
|
|
||||||
Copyright © 2017 Gabriel Détraz
|
Copyright © 2017 Gabriel Détraz
|
||||||
Copyright © 2017 Goulven Kermarec
|
Copyright © 2017 Lara Kermarec
|
||||||
Copyright © 2017 Augustin Lemesle
|
Copyright © 2017 Augustin Lemesle
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -34,6 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
<th>{% trans "Price" %}</th>
|
<th>{% trans "Price" %}</th>
|
||||||
<th>{% trans "Subscription type" %}</th>
|
<th>{% trans "Subscription type" %}</th>
|
||||||
<th>{% trans "Duration (in months)" %}</th>
|
<th>{% trans "Duration (in months)" %}</th>
|
||||||
|
<th>{% trans "Duration (in days)" %}</th>
|
||||||
<th>{% trans "Concerned users" %}</th>
|
<th>{% trans "Concerned users" %}</th>
|
||||||
<th>{% trans "Available for everyone" %}</th>
|
<th>{% trans "Available for everyone" %}</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
|
@ -45,6 +46,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
<td>{{ article.prix }}</td>
|
<td>{{ article.prix }}</td>
|
||||||
<td>{{ article.type_cotisation }}</td>
|
<td>{{ article.type_cotisation }}</td>
|
||||||
<td>{{ article.duration }}</td>
|
<td>{{ article.duration }}</td>
|
||||||
|
<td>{{ article.duration_days }}</td>
|
||||||
<td>{{ article.type_user }}</td>
|
<td>{{ article.type_user }}</td>
|
||||||
<td>{{ article.available_for_everyone | tick }}</td>
|
<td>{{ article.available_for_everyone | tick }}</td>
|
||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
|
|
|
@ -4,7 +4,7 @@ se veut agnostique au réseau considéré, de manière à être installable en
|
||||||
quelques clics.
|
quelques clics.
|
||||||
|
|
||||||
Copyright © 2017 Gabriel Détraz
|
Copyright © 2017 Gabriel Détraz
|
||||||
Copyright © 2017 Goulven Kermarec
|
Copyright © 2017 Lara Kermarec
|
||||||
Copyright © 2017 Augustin Lemesle
|
Copyright © 2017 Augustin Lemesle
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -4,7 +4,7 @@ se veut agnostique au réseau considéré, de manière à être installable en
|
||||||
quelques clics.
|
quelques clics.
|
||||||
|
|
||||||
Copyright © 2017 Gabriel Détraz
|
Copyright © 2017 Gabriel Détraz
|
||||||
Copyright © 2017 Goulven Kermarec
|
Copyright © 2017 Lara Kermarec
|
||||||
Copyright © 2017 Augustin Lemesle
|
Copyright © 2017 Augustin Lemesle
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -4,7 +4,7 @@ se veut agnostique au réseau considéré, de manière à être installable en
|
||||||
quelques clics.
|
quelques clics.
|
||||||
|
|
||||||
Copyright © 2017 Gabriel Détraz
|
Copyright © 2017 Gabriel Détraz
|
||||||
Copyright © 2017 Goulven Kermarec
|
Copyright © 2017 Lara Kermarec
|
||||||
Copyright © 2017 Augustin Lemesle
|
Copyright © 2017 Augustin Lemesle
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -31,7 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans "Payment type" %}</th>
|
<th>{% trans "Payment type" %}</th>
|
||||||
<th>{% trans "Is available for everyone" %}</th>
|
<th>{% trans "Available for everyone" %}</th>
|
||||||
<th>{% trans "Custom payment method" %}</th>
|
<th>{% trans "Custom payment method" %}</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -5,7 +5,7 @@ se veut agnostique au réseau considéré, de manière à être installable en
|
||||||
quelques clics.
|
quelques clics.
|
||||||
|
|
||||||
Copyright © 2017 Gabriel Détraz
|
Copyright © 2017 Gabriel Détraz
|
||||||
Copyright © 2017 Goulven Kermarec
|
Copyright © 2017 Lara Kermarec
|
||||||
Copyright © 2017 Augustin Lemesle
|
Copyright © 2017 Augustin Lemesle
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -45,12 +45,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans "Profile" %}</th>
|
<th>{% trans "Profile" %}</th>
|
||||||
<th>
|
<th>
|
||||||
{% trans "Last name" as tr_last_name %}
|
{% trans "First name" as tr_first_name %}
|
||||||
{% include 'buttons/sort.html' with prefix='control' col='name' text=tr_last_name %}
|
{% include 'buttons/sort.html' with prefix='control' col='name' text=tr_first_name %}
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
{% trans "First name" as tr_first_name %}
|
{% trans "Surname" as tr_surname %}
|
||||||
{% include 'buttons/sort.html' with prefix='control' col='surname' text=tr_first_name %}
|
{% include 'buttons/sort.html' with prefix='control' col='surname' text=tr_surname %}
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
{% trans "Invoice ID" as tr_invoice_id %}
|
{% trans "Invoice ID" as tr_invoice_id %}
|
||||||
|
@ -104,8 +104,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
{% trans "Edit" as tr_edit %}
|
{% trans "Confirm" as tr_confirm %}
|
||||||
{% bootstrap_button tr_edit button_type='submit' icon='ok' button_class='btn-success' %}
|
{% bootstrap_button tr_confirm button_type='submit' icon='ok' button_class='btn-success' %}
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -5,7 +5,7 @@ se veut agnostique au réseau considéré, de manière à être installable en
|
||||||
quelques clics.
|
quelques clics.
|
||||||
|
|
||||||
Copyright © 2017 Gabriel Détraz
|
Copyright © 2017 Gabriel Détraz
|
||||||
Copyright © 2017 Goulven Kermarec
|
Copyright © 2017 Lara Kermarec
|
||||||
Copyright © 2017 Augustin Lemesle
|
Copyright © 2017 Augustin Lemesle
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -33,7 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
<form class="form" method="post">
|
<form class="form" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<h4>
|
<h4>
|
||||||
{% blocktrans %}Warning: are you sure you really want to delete this {{ object_name }} object ( {{ objet }} )?{% endblocktrans %}
|
{% blocktrans %}Warning: are you sure you really want to delete this {{ objet_name }} object ( {{ objet }} )?{% endblocktrans %}
|
||||||
</h4>
|
</h4>
|
||||||
{% trans "Confirm" as tr_confirm %}
|
{% trans "Confirm" as tr_confirm %}
|
||||||
{% bootstrap_button tr_confirm button_type='submit' icon='trash' button_class='btn-danger' %}
|
{% bootstrap_button tr_confirm button_type='submit' icon='trash' button_class='btn-danger' %}
|
||||||
|
|
|
@ -5,7 +5,7 @@ se veut agnostique au réseau considéré, de manière à être installable en
|
||||||
quelques clics.
|
quelques clics.
|
||||||
|
|
||||||
Copyright © 2017 Gabriel Détraz
|
Copyright © 2017 Gabriel Détraz
|
||||||
Copyright © 2017 Goulven Kermarec
|
Copyright © 2017 Lara Kermarec
|
||||||
Copyright © 2017 Augustin Lemesle
|
Copyright © 2017 Augustin Lemesle
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -6,17 +6,17 @@ Nous vous remercions pour votre achat auprès de {{asso_name}} et nous vous en j
|
||||||
|
|
||||||
En cas de question, n’hésitez pas à nous contacter par mail à {{contact_mail}}.
|
En cas de question, n’hésitez pas à nous contacter par mail à {{contact_mail}}.
|
||||||
|
|
||||||
Cordialement,
|
Respectueusement,
|
||||||
L’équipe de {{asso_name}}
|
L’équipe de {{asso_name}}.
|
||||||
|
|
||||||
|
|
||||||
=== English version ===
|
=== English version ===
|
||||||
|
|
||||||
Dear {{name}},
|
Hello {{name}},
|
||||||
|
|
||||||
Thank you for your purchase. Here is your invoice.
|
Thank you for your purchase at {{asso_name}}. Here is your invoice.
|
||||||
|
|
||||||
Should you need extra information, you can email us at {{contact_mail}}.
|
Should you need extra information, do not hesitate to email us at {{contact_mail}}.
|
||||||
|
|
||||||
Best regards,
|
Regards,
|
||||||
{{ asso_name }}'s team
|
The {{ asso_name }} team.
|
||||||
|
|
|
@ -1,22 +1,23 @@
|
||||||
Bonjour {{name}} !
|
Bonjour {{name}} !
|
||||||
|
|
||||||
Nous vous informons que votre cotisation auprès de {{asso_name}} a été acceptée. Vous voilà donc membre de l'association.
|
Nous vous informons que votre cotisation auprès de {{asso_name}} a été acceptée. Vous voilà donc membre de l'association jusqu'au {{ date_end|date:"d/m/Y" }}.
|
||||||
|
|
||||||
Vous trouverez en pièce jointe un reçu.
|
Vous trouverez en pièce jointe un reçu.
|
||||||
|
|
||||||
Pour nous faire part de toute remarque, suggestion ou problème vous pouvez nous envoyer un mail à {{asso_email}}.
|
Pour nous faire part de toute remarque, suggestion ou problème vous pouvez nous envoyer un mail à {{asso_email}}.
|
||||||
|
|
||||||
À bientôt,
|
Respectueusement,
|
||||||
L'équipe de {{asso_name}}.
|
L'équipe de {{asso_name}}.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Your subscription to {{asso_name}} has just been accepted. You are now a full member of {{asso_name}}.
|
Hello {{name}}!
|
||||||
|
|
||||||
|
Your subscription to {{asso_name}} has just been accepted. You are now a full member of {{asso_name}} until {{ date_end|date:"d/m/Y" }}.
|
||||||
|
|
||||||
You will find with this email a subscription voucher.
|
You will find with this email a subscription voucher.
|
||||||
|
|
||||||
For any information, suggestion or problem, you can contact us via email at
|
To express any comment, suggestion or problem, you can send us an email to {{asso_email}}.
|
||||||
{{asso_email}}.
|
|
||||||
|
|
||||||
Regards,
|
Regards,
|
||||||
The {{asso_name}} team.
|
The {{asso_name}} team.
|
||||||
|
|
|
@ -5,7 +5,7 @@ se veut agnostique au réseau considéré, de manière à être installable en
|
||||||
quelques clics.
|
quelques clics.
|
||||||
|
|
||||||
Copyright © 2017 Gabriel Détraz
|
Copyright © 2017 Gabriel Détraz
|
||||||
Copyright © 2017 Goulven Kermarec
|
Copyright © 2017 Lara Kermarec
|
||||||
Copyright © 2017 Augustin Lemesle
|
Copyright © 2017 Augustin Lemesle
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -44,9 +44,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
{% blocktrans %}Current balance: {{ balance }} €{% endblocktrans %}
|
{% blocktrans %}Current balance: {{ balance }} €{% endblocktrans %}
|
||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if factureform %}
|
|
||||||
{% bootstrap_form_errors factureform %}
|
|
||||||
{% endif %}
|
|
||||||
{% if discount_form %}
|
{% if discount_form %}
|
||||||
{% bootstrap_form_errors discount_form %}
|
{% bootstrap_form_errors discount_form %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -90,7 +87,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
{% if articlesformset %}
|
{% if articlesformset %}
|
||||||
var prices = {};
|
var prices = {};
|
||||||
{% for article in articlelist %}
|
{% for article in articlelist %}
|
||||||
prices[{{ article.id|escapejs }}] = {{ article.prix }};
|
prices[{{ article.id|escapejs }}] = "{{ article.prix }}";
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
var template = `Article :
|
var template = `Article :
|
||||||
|
@ -124,7 +121,7 @@ function update_price(){
|
||||||
if (article == '') {
|
if (article == '') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
article_price = prices[article];
|
article_price = parseFloat(prices[article].replace(',', '.'));
|
||||||
quantity = document.getElementById(
|
quantity = document.getElementById(
|
||||||
'id_form-' + i.toString() + '-quantity').value;
|
'id_form-' + i.toString() + '-quantity').value;
|
||||||
price += article_price * quantity;
|
price += article_price * quantity;
|
||||||
|
|
|
@ -5,7 +5,7 @@ se veut agnostique au réseau considéré, de manière à être installable en
|
||||||
quelques clics.
|
quelques clics.
|
||||||
|
|
||||||
Copyright © 2017 Gabriel Détraz
|
Copyright © 2017 Gabriel Détraz
|
||||||
Copyright © 2017 Goulven Kermarec
|
Copyright © 2017 Lara Kermarec
|
||||||
Copyright © 2017 Augustin Lemesle
|
Copyright © 2017 Augustin Lemesle
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -5,7 +5,7 @@ se veut agnostique au réseau considéré, de manière à être installable en
|
||||||
quelques clics.
|
quelques clics.
|
||||||
|
|
||||||
Copyright © 2017 Gabriel Détraz
|
Copyright © 2017 Gabriel Détraz
|
||||||
Copyright © 2017 Goulven Kermarec
|
Copyright © 2017 Lara Kermarec
|
||||||
Copyright © 2017 Augustin Lemesle
|
Copyright © 2017 Augustin Lemesle
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -30,14 +30,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
{% block title %}{% trans "Articles" %}{% endblock %}
|
{% block title %}{% trans "Articles" %}{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h2>{% trans "List of article types" %}</h2>
|
<h2>{% trans "List of articles" %}</h2>
|
||||||
{% can_create Article %}
|
{% can_create Article %}
|
||||||
<a class="btn btn-primary btn-sm" role="button" href="{% url 'cotisations:add-article' %}">
|
<a class="btn btn-primary btn-sm" role="button" href="{% url 'cotisations:add-article' %}">
|
||||||
<i class="fa fa-cart-plus"></i> {% trans "Add an article type" %}
|
<i class="fa fa-plus"></i> {% trans "Add an article" %}
|
||||||
</a>
|
</a>
|
||||||
{% acl_end %}
|
{% acl_end %}
|
||||||
<a class="btn btn-danger btn-sm" role="button" href="{% url 'cotisations:del-article' %}">
|
<a class="btn btn-danger btn-sm" role="button" href="{% url 'cotisations:del-article' %}">
|
||||||
<i class="fa fa-trash"></i> {% trans "Delete one or several article types" %}
|
<i class="fa fa-trash"></i> {% trans "Delete one or several articles" %}
|
||||||
</a>
|
</a>
|
||||||
{% include 'cotisations/aff_article.html' with article_list=article_list %}
|
{% include 'cotisations/aff_article.html' with article_list=article_list %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -5,7 +5,7 @@ se veut agnostique au réseau considéré, de manière à être installable en
|
||||||
quelques clics.
|
quelques clics.
|
||||||
|
|
||||||
Copyright © 2017 Gabriel Détraz
|
Copyright © 2017 Gabriel Détraz
|
||||||
Copyright © 2017 Goulven Kermarec
|
Copyright © 2017 Lara Kermarec
|
||||||
Copyright © 2017 Augustin Lemesle
|
Copyright © 2017 Augustin Lemesle
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -33,7 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
<h2>{% trans "List of banks" %}</h2>
|
<h2>{% trans "List of banks" %}</h2>
|
||||||
{% can_create Banque %}
|
{% can_create Banque %}
|
||||||
<a class="btn btn-primary btn-sm" role="button" href="{% url 'cotisations:add-banque' %}">
|
<a class="btn btn-primary btn-sm" role="button" href="{% url 'cotisations:add-banque' %}">
|
||||||
<i class="fa fa-cart-plus"></i> {% trans "Add a bank" %}
|
<i class="fa fa-plus"></i> {% trans "Add a bank" %}
|
||||||
</a>
|
</a>
|
||||||
{% acl_end %}
|
{% acl_end %}
|
||||||
<a class="btn btn-danger btn-sm" role="button" href="{% url 'cotisations:del-banque' %}">
|
<a class="btn btn-danger btn-sm" role="button" href="{% url 'cotisations:del-banque' %}">
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue