Commit 7cb8a2dc authored by Patrick Colmant's avatar Patrick Colmant

Use of natural key export, minimalist : import-export xlsx, export docx, order UI, send mail

parent 7706def0
......@@ -28,6 +28,9 @@ pip install cmsplugin-filer
pip install django-reversion
pip install django_compressor
pip install django-admin-sortable2
pip install openpyxl
sudo apt-get install libxml2-dev libxslt1-dev
pip install docx
# pip install django_debug_toolbar
# pip install django-dajaxice ! not working with Django 1.6
# pip install django-custom-user
......
......@@ -7,7 +7,21 @@
processes = 2
buffer-size = 8192
env = DJANGO_SETTINGS_MODULE=mysite.$REPANIER.BE$_settings
env = DJANGO_SETTINGS_MODULE_SITE_ID=1
env = DJANGO_SETTINGS_MODULE_DEBUG=False
env = DJANGO_SETTINGS_MODULE_DATABASE_NAME=$NAME$
env = DJANGO_SETTINGS_MODULE_DATABASE_USER=$USER$
env = DJANGO_SETTINGS_MODULE_DATABASE_PASSWORD=$PASSWORD$
env = DJANGO_SETTINGS_MODULE_DATABASE_HOST=127.0.0.1
env = DJANGO_SETTINGS_MODULE_DATABASE_PORT=5432
env = DJANGO_SETTINGS_MODULE_SECRET_KEY=$SECRET_KEY$
env = DJANGO_SETTINGS_MODULE_EMAIL_HOST=$EMAIL_HOST$
env = DJANGO_SETTINGS_MODULE_EMAIL_HOST_USER=$EMAIL_HOST_USER$
env = DJANGO_SETTINGS_MODULE_EMAIL_HOST_PASSWORD=$EMAIL_HOST_PASSWORD$
env = DJANGO_SETTINGS_MODULE_EMAIL_PORT=$EMAIL_PORT$
env = DJANGO_SETTINGS_MODULE_EMAIL_USE_TLS=True
env = DJANGO_SETTINGS_MODULE_ADMIN_NAME=$ADMIN_NAME$
env = DJANGO_SETTINGS_MODULE_ADMIN_EMAIL=$ADMIN_EMAIL$
wsgi-file = /$PATH_TO$/production/mysite/mysite/wsgi.py
virtualenv = /$PATH_TO$/production/
chdir = /$PATH_TO$/production/mysite/
......
# -*- coding: utf-8 -*-
from production_settings import *
from common_settings import *
### Site 4 specific parameters
SITE_ID = 4
ALLOWED_HOSTS = ['apero.$REPANIER.BE$','apero.$REPANIER.LOCAL$']
SITE_ID = 4 if os.getenv('DJANGO_SETTINGS_MODULE_SITE_ID','') == '4' else 1 / 0
ALLOWED_HOSTS = ['apero.$REPANIER.BE$',]
EMAIL_SUBJECT_PREFIX = '['+ ALLOWED_HOSTS[0] +']'
MEDIA_ROOT = os.path.join(PROJECT_DIR, "media", ALLOWED_HOSTS[0], "public")
TEMPLATE_DIRS = (
......
......@@ -8,16 +8,45 @@ PROJECT_PATH = os.path.split(os.path.abspath(os.path.dirname(__file__)))[0]
PROJECT_DIR = os.path.realpath(os.path.dirname(__file__))
os.sys.path.insert(0, os.path.dirname(PROJECT_DIR))
######################
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
'NAME': os.getenv('DJANGO_SETTINGS_MODULE_DATABASE_NAME',''), # Or path to database file if using sqlite3.
# The following settings are not used with sqlite3:
'USER': os.getenv('DJANGO_SETTINGS_MODULE_DATABASE_USER',''),
'PASSWORD': os.getenv('DJANGO_SETTINGS_MODULE_DATABASE_PASSWORD',''),
# Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP.
'HOST': os.getenv('DJANGO_SETTINGS_MODULE_DATABASE_HOST',''), # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP.
'PORT': os.getenv('DJANGO_SETTINGS_MODULE_DATABASE_PORT',''), # Set to empty string for default.
}
}
SECRET_KEY = os.getenv('DJANGO_SETTINGS_MODULE_SECRET_KEY','')
EMAIL_HOST = os.getenv('DJANGO_SETTINGS_MODULE_EMAIL_HOST','')
EMAIL_HOST_USER = os.getenv('DJANGO_SETTINGS_MODULE_EMAIL_HOST_USER','')
EMAIL_HOST_PASSWORD = os.getenv('DJANGO_SETTINGS_MODULE_EMAIL_HOST_PASSWORD','')
EMAIL_PORT = os.getenv('DJANGO_SETTINGS_MODULE_EMAIL_PORT','')
EMAIL_USE_TLS = True if os.getenv('DJANGO_SETTINGS_MODULE_EMAIL_USE_TLS','') == 'True' else False
###################### I18N
TIME_ZONE = 'Europe/Brussels'
LANGUAGE_CODE = 'fr-BE'
# 'fr-be'
###################### DEBUG
# Defined into /etc/uwsgi/apps-available/*.ini
DEBUG = True if os.getenv('DJANGO_SETTINGS_MODULE_DEBUG','') == 'True' else False
TEMPLATE_DEBUG = DEBUG
ADMINS = (
(
os.getenv('DJANGO_SETTINGS_MODULE_ADMIN_NAME',''),
os.getenv('DJANGO_SETTINGS_MODULE_ADMIN_EMAIL','')
),
)
##################### Django & Django CMS
LANGUAGES = [
......@@ -84,8 +113,13 @@ INSTALLED_APPS = (
'djangocms_admin_style', # note this needs to be above
# the 'django.contrib.admin' entry
'django.contrib.admin',
'adminsortable',
# 'cms.plugins.file',
'cms.plugins.googlemap',
'cms.plugins.link',
# 'cms.plugins.picture',
# 'cms.plugins.teaser',
# 'cms.plugins.video',
'filer',
'easy_thumbnails',
'cmsplugin_filer_file',
......@@ -94,11 +128,14 @@ INSTALLED_APPS = (
'cmsplugin_filer_teaser',
'cmsplugin_filer_video',
'reversion',
'adminsortable',
# 'wkhtmltopdf', # --> PDF
)
# WKHTMLTOPDF_CMD = '/usr/bin/wkhtmltopdf.sh' # --> PDF
CMS_PERMISSION = False # When set to True, don't forget 'cms.middleware.user.CurrentUserMiddleware'
CMS_PUBLIC_FOR = 'all'
# CMS_PUBLIC_FOR = 'staff'
CMS_SHOW_START_DATE = False
CMS_SHOW_END_DATE = False
CMS_SEO_FIELDS = False
......@@ -117,6 +154,7 @@ CKEDITOR_SETTINGS = {
# 'stylesSet' : 'default:%sckeditor/styles.js' % STATIC_URL,
'stylesSet' : 'my_styles:%sjs/ckeditor-styles.js' % STATIC_URL,
'autoGrow_onStartup' : True,
# 'height' : '450px',
'emailProtection' : '2',
'toolbar_CMS2': [
['Undo', 'Redo'],
......@@ -148,6 +186,7 @@ THUMBNAIL_PROCESSORS = (
)
THUMBNAIL_DEBUG = DEBUG
# https://docs.djangoproject.com/en/1.5/howto/static-files/
STATIC_ROOT = os.path.join(PROJECT_DIR, "collect-static")
STATIC_URL = "/static/"
MEDIA_URL = "/media/"
......@@ -161,6 +200,8 @@ SOUTH_TESTS_MIGRATE = DEBUG
##################### Repanier
AUTHENTICATION_BACKENDS = ('repanier.auth_backend.RepanierCustomBackend',)
# ADMIN_LOGIN = 'pise'
# ADMIN_PASSWORD = 'raspberry'
INSTALLED_APPS += (
'repanier',
)
......@@ -244,3 +285,116 @@ CMS_CACHE_DURATIONS = {
'menus' : 15, # default 3600
'permissions' : 3600 # default: 3600
}
###################### EASYMAP
#EASY_MAPS_CENTER = ( 50.630545,3.776955 )
#INSTALLED_APPS += (
# 'easy_maps',
#)
###################### Debug Toolbar
# if( DEBUG):
# INTERNAL_IPS = ('127.0.0.1',)
# MIDDLEWARE_CLASSES += (
# 'debug_toolbar.middleware.DebugToolbarMiddleware',
# )
# DEBUG_TOOLBAR_PANELS = (
# 'debug_toolbar.panels.version.VersionDebugPanel',
# 'debug_toolbar.panels.timer.TimerDebugPanel',
# 'debug_toolbar.panels.settings_vars.SettingsVarsDebugPanel',
# 'debug_toolbar.panels.headers.HeaderDebugPanel',
# 'debug_toolbar.panels.profiling.ProfilingDebugPanel',
# 'debug_toolbar.panels.request_vars.RequestVarsDebugPanel',
# 'debug_toolbar.panels.sql.SQLDebugPanel',
# 'debug_toolbar.panels.template.TemplateDebugPanel',
# 'debug_toolbar.panels.cache.CacheDebugPanel',
# 'debug_toolbar.panels.signals.SignalDebugPanel',
# 'debug_toolbar.panels.logger.LoggingPanel',
# )
# CACHE_BACKEND = 'dummy://'
# LOGGING = {
# 'version': 1,
# 'disable_existing_loggers': True,
# 'formatters': {
# 'verbose': {
# 'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
# },
# },
# 'handlers': {
# 'null': {
# 'level':'DEBUG',
# 'class':'django.utils.log.NullHandler',
# },
# 'console':{
# 'level':'DEBUG',
# 'class':'logging.StreamHandler',
# 'formatter': 'verbose'
# },
# },
# 'loggers': {
# 'django': {
# 'handlers':['null'],
# 'propagate': True,
# 'level':'INFO',
# },
# 'django.request': {
# 'handlers': ['console'],
# 'level': 'ERROR',
# 'propagate': False,
# },
# 'django.db.backends': {
# 'handlers': ['console'],
# 'level': 'DEBUG',
# 'propagate': False,
# },
# }
# }
# INSTALLED_APPS += (
# 'debug_toolbar',
# )
# def custom_show_toolbar(request):
# return DEBUG # Always show toolbar, for example purposes only.
# DEBUG_TOOLBAR_CONFIG = {
# 'SHOW_TOOLBAR_CALLBACK': custom_show_toolbar,
# 'INTERCEPT_REDIRECTS': False,
# 'ENABLE_STACKTRACES' : True,
# }
if DEBUG:
import logging
l = logging.getLogger('django.db.backends')
l.setLevel(logging.DEBUG)
l.addHandler(logging.StreamHandler())
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
'handlers': {
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
},'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
},
},
'loggers': {
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': True,
},'django.db.backends': {
'level': 'DEBUG',
'handlers': ['console'],
},
}
}
\ No newline at end of file
# -*- coding: utf-8 -*-
from production_settings import *
from common_settings import *
### Site 5 specific parameters
SITE_ID = 5
ALLOWED_HOSTS = ['lelensois.$REPANIER.BE$','lelensois.$REPANIER.LOCAL$']
SITE_ID = 5 if os.getenv('DJANGO_SETTINGS_MODULE_SITE_ID','') == '5' else 1 / 0
ALLOWED_HOSTS = ['lelensois.$REPANIER.BE$',]
EMAIL_SUBJECT_PREFIX = '['+ ALLOWED_HOSTS[0] +']'
MEDIA_ROOT = os.path.join(PROJECT_DIR, "media", ALLOWED_HOSTS[0], "public")
TEMPLATE_DIRS = (
......
# -*- coding: utf-8 -*-
from production_settings import *
from common_settings import *
### Site 2 specific parameters
SITE_ID = 2
ALLOWED_HOSTS = ['producer.$REPANIER.BE$','producer.$REPANIER.LOCAL$']
SITE_ID = 2 if os.getenv('DJANGO_SETTINGS_MODULE_SITE_ID','') == '2' else 1 / 0
ALLOWED_HOSTS = ['producer.$REPANIER.BE$',]
EMAIL_SUBJECT_PREFIX = '['+ ALLOWED_HOSTS[0] +']'
MEDIA_ROOT = os.path.join(PROJECT_DIR, "media", ALLOWED_HOSTS[0], "public")
TEMPLATE_DIRS = (
......
# -*- coding: utf-8 -*-
from common_settings import *
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
'NAME': '$NAME$', # Or path to database file if using sqlite3.
# The following settings are not used with sqlite3:
'USER': '$USER$',
'PASSWORD': '$PASSWORD$',
'HOST': '127.0.0.1', # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP.
'PORT': '5432', # Set to empty string for default.
}
}
SECRET_KEY = '$DJANGO_SECRET_KEY$'
# -*- coding: utf-8 -*-
from production_settings import *
from common_settings import *
### Site 3 specific parameters
SITE_ID = 3
ALLOWED_HOSTS = ['ptidej.$REPANIER.BE$','ptidej.$REPANIER.LOCAL$']
SITE_ID = 3 if os.getenv('DJANGO_SETTINGS_MODULE_SITE_ID','') == '3' else 1 / 0
ALLOWED_HOSTS = ['ptidej.$REPANIER.BE$',]
EMAIL_SUBJECT_PREFIX = '['+ ALLOWED_HOSTS[0] +']'
MEDIA_ROOT = os.path.join(PROJECT_DIR, "media", ALLOWED_HOSTS[0], "public")
TEMPLATE_DIRS = (
......
# -*- coding: utf-8 -*-
from production_settings import *
from common_settings import *
### Site 1 specific parameters
SITE_ID = 1
ALLOWED_HOSTS = ['$REPANIER.BE$','$REPANIER.LOCAL$']
SITE_ID = 1 if os.getenv('DJANGO_SETTINGS_MODULE_SITE_ID','') == '1' else 1 / 0
ALLOWED_HOSTS = ['.$REPANIER.BE$',]
EMAIL_SUBJECT_PREFIX = '['+ ALLOWED_HOSTS[0] +']'
MEDIA_ROOT = os.path.join(PROJECT_DIR, "media", ALLOWED_HOSTS[0], "public")
TEMPLATE_DIRS = (
......@@ -11,13 +11,6 @@ TEMPLATE_DIRS = (
)
CACHE_MIDDLEWARE_KEY_PREFIX = ALLOWED_HOSTS[0]
CMS_CACHE_PREFIX = ALLOWED_HOSTS[0]
# BEGIN OF : Use email instead of username as login name
# from django.contrib.auth.models import User
## ImportError: Could not import settings 'mysite.repanier_settings' (Is it on sys.path? Is there an import error in the settings file?): cannot import name auth
# User.USERNAME_FIELD = 'email'
# User.REQUIRED_FIELDS.remove('email')
# User._meta.get_field('email')._unique = True
# END OF : Use email instead of username as login name
CMS_TEMPLATES = (
('home.html', gettext("Homepage")),
......
......@@ -75,15 +75,11 @@
<footer class="row">
<div class="large-12 columns">
<hr />
<div class="row">
<div class="large-12 columns">
{% block footer %}
{% placeholder 'footer' or %}
<p>Nous joindre : coordi at repanier.be | Participer : <a href="https://github.com/pcolmant/repanier">github</a> | Repanier utilise <a href="https://www.django-cms.org/en/">Django CMS 3</a> et <a href="http://foundation.zurb.com/">Foundation 5</a></p>
{% endplaceholder %}
{% endblock %}
</div>
</div>
{% block footer %}
{% placeholder 'footer' or %}
<p>Nous joindre : coordi at repanier.be | Participer : <a href="https://github.com/pcolmant/repanier">github</a> | Repanier utilise <a href="https://www.django-cms.org/en/">Django CMS 3</a> et <a href="http://foundation.zurb.com/">Foundation 5</a></p>
{% endplaceholder %}
{% endblock %}
</div>
</footer>
{% addtoblock "js" %}<script src="{{ STATIC_URL }}foundation/js/vendor/jquery.js"></script>{% endaddtoblock %}
......
......@@ -2,6 +2,6 @@
{% load cms_tags %}
{% block sub_content %}
<h1>{% page_attribute "page_title" %}</h1>
<h1>{% page_attribute "page_title" %}</h1>
{% placeholder subpage_content %}
{% endblock %}
\ No newline at end of file
......@@ -2,11 +2,7 @@
{% load cms_tags %}
{% block base_content %}
<div class="row">
<div class="col-md-12">
{% block sub_content %}{% endblock %}
</div>
</div>
{% block sub_content %}{% endblock %}
{% endblock %}
......@@ -3,9 +3,13 @@ import re
from const import *
from django.conf import settings
from django.conf.urls import patterns, url
from django.contrib import admin
from django.contrib.auth import get_user_model
from django.contrib.auth.models import User
from django.core import urlresolvers
from django.http import HttpResponse
from django.utils.translation import ugettext_lazy as _
from django.utils import timezone
from django.core import validators
......@@ -14,8 +18,8 @@ from django.db import models
from django.db.models import Q, F
from django import forms
# from adminsortable.admin import SortableAdminMixin
from repanier.adminsortable import SortableAdminMixin
from adminsortable.admin import SortableAdminMixin
# from repanier.adminsortable import SortableAdminMixin
from repanier.models import LUT_ProductionMode
from repanier.models import LUT_DepartmentForCustomer
......@@ -23,6 +27,7 @@ from repanier.models import LUT_DepartmentForProducer
from repanier.models import LUT_PermanenceRole
from repanier.models import Producer
from repanier.models import Permanence
from repanier.models import SiteProducer
from repanier.models import Customer
from repanier.models import SiteCustomer
......@@ -51,10 +56,10 @@ from django.contrib.admin import SimpleListFilter
class ProductFilterBySiteProducer(SimpleListFilter):
# Human-readable title which will be displayed in the
# right admin sidebar.
# Human-readable title which will be displayed in the
# right admin sidebar.
title = _("producers")
# Parameter for the filter that will be used in the URL query.
# Parameter for the filter that will be used in the URL query.
parameter_name = 'site_producer'
def lookups(self, request, model_admin):
......@@ -68,7 +73,7 @@ class ProductFilterBySiteProducer(SimpleListFilter):
# This list is a collection of site producer.id, .name
return [(c.id, c.short_profile_name) for c in
SiteProducer.objects.all().active().with_login()
]
]
def queryset(self, request, queryset):
"""
......@@ -91,7 +96,7 @@ class ProductFilterByDepartmentForProducer(SimpleListFilter):
# This list is a collection of site department.id, .name
return [(c.id, c.short_name) for c in
LUT_DepartmentForProducer.objects.all().active()
]
]
def queryset(self, request, queryset):
# This query set is a collection of products
......@@ -113,7 +118,7 @@ class ProductFilterByDepartmentForThisProducer(SimpleListFilter):
# return []
return [('all', _('All'))] + [(c.id, c.short_name) for c in
LUT_DepartmentForProducer.objects.all().active().filter(product__in=inner_qs)
]
]
def choices(self, cl):
for lookup, title in self.lookup_choices:
......@@ -194,17 +199,18 @@ class UserDataForm(forms.ModelForm):
if field not in self._errors:
self._errors[field]= self.error_class([msg])
def clean(self):
def clean(self, *args, **kwargs):
# The SiteStaff has no first_name or last_name because it's a function with login/pwd.
# A SiteCustomer with a first_name and last_name is responsible of this funcition.
if not self['first_name'].html_name in self.data:
if 'first_name' in self._errors:
del self._errors['first_name']
self.data['first_name'] = self.fields['first_name'].initial
if not self['last_name'].html_name in self.data:
if 'last_name' in self._errors:
del self._errors['last_name']
self.data['last_name'] = self.fields['last_name'].initial
if any(self.errors):
if not self['first_name'].html_name in self.data:
if 'first_name' in self._errors:
del self._errors['first_name']
self.data['first_name'] = self.fields['first_name'].initial
if not self['last_name'].html_name in self.data:
if 'last_name' in self._errors:
del self._errors['last_name']
self.data['last_name'] = self.fields['last_name'].initial
# Check that the password is set when it's a new user.
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
......@@ -242,7 +248,7 @@ class UserDataForm(forms.ModelForm):
pass
if user != None:
self.error('username',_('The given username is used by another user'))
super(UserDataForm, self).clean()
super(UserDataForm, self).clean(*args, **kwargs)
return self.cleaned_data
def save(self, *args, **kwargs):
......@@ -255,14 +261,12 @@ class UserDataForm(forms.ModelForm):
last_name = self.data['last_name']
user = None
if change:
user=User.objects.get(id=self.instance.user.id)
user=User.objects.get(id=self.instance.user_id)
user.username = username
user.email = email
user.first_name = first_name