Vous voici sur le Git Rural du CRAW

...
 
Commits (5)
*.pyc
*.orig
*.ipynb
*.key
.pylintrc
.vscode
.DS_Store
......
......@@ -10,7 +10,7 @@ TresoFerme, a simplified farm cash flow management tool, to help producers reapp
## Installation
### 1. Clone repo and configure virtualenv
#### 1. Clone repo and configure virtualenv
```bash
$ git clone git@gitrural.cra.wallonie.be:craw-app/tresoferme.git
......@@ -20,14 +20,14 @@ $ pipenv shell
$ cd source # DO NOT FORGET!!!
```
### 2. Check django install
#### 2. Check django install
```bash
(tresoferme) $ python -m django --version
# This should return django version number, 3 or upper, like 3.0.7
```
### 3. Check everything has been correctly installed
#### 3. Check everything has been correctly installed
```bash
(tresoferme) $ python manage.py check
```
......@@ -37,7 +37,7 @@ File "/home/pat/.local/share/virtualenvs/tresoferme-NMZJAftp/lib/python3.6/site-
from django.utils.six import BytesIO
ModuleNotFoundError: No module named 'django.utils.six'
```
Error raised until [django3 features](https://github.com/nigma/django-easy-pdf/pull/73/files) integration
Error raised since [django3 features](https://github.com/nigma/django-easy-pdf/pull/73/files) is not yet integrated in latest version
Edit the file and change **Line 12**
......@@ -51,12 +51,13 @@ to
from six import BytesIO
```
### 4. run the shell accounts4sqlite.sh
#### 4. run the shell source.accounts4sqlite.sh
```bash
(tresoferme) $ sh accounts4sqlite.sh
```
This shell is just changing profile foreign key from User to Profile in "source.accounts.models.py" file
### 5. Launch localhost server
#### 5. Launch localhost server
```bash
(tresoferme) $ python manage.py runserver
```
......@@ -64,6 +65,31 @@ from six import BytesIO
Load the site at http://127.0.0.1:8000
#### 6. Connect using the following credentials:
usernames: admin, manager, demo, eleveur, maraicher
password: mybestpasswd
1. admin: allows to access django-admin and change key parameters in the database ie: django_site, money_unitlist, accounts_supportstructure, etc.
2. manager: allows you to manage you users: eleveur & maraicher. Go to top right menu and select 'Mes utilisateurs'
3. demo: simple test user
4. eleveur: stockbreeding example
5. maraicher: market gardening example
## Mailing from TresoFerme
If you want to use mailing from localhost (@SignIn for instance), you have to adapt EMAIL_HOST_USER and EMAIL_HOST_PASSWORD in settings_localhost.json file
```json
"EMAIL_HOST_USER": "hello@google.be",
"EMAIL_HOST_PASSWORD": "mybestpasswd",
```
## Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
......
......@@ -3,7 +3,7 @@ __email__ = 'p.houben@cra.wallonie.be'
__copyright__ = 'Copyright 2018-2020, Patrick HOUBEN'
__license__ = 'MIT'
__date__ = '2020-05-01'
__version__ = '1.3.1'
__version__ = '1.4.1'
__status__ = 'Stable'
# Version synonym
......
......@@ -265,14 +265,14 @@ class ProfileSignUpForm(PhoneCheck, UserCreationForm):
new_order = first_fields + last_fields
self.fields = OrderedDict(new_order)
def clean_mobile(self):
if self.cleaned_data['mobile'] is None:
return None
elif self._test_phone(self.cleaned_data['mobile']):
return self.set_32(self.cleaned_data['mobile'])
else:
raise ValidationError(_('Respecter le format: (+32 ou 0) \
suivi de 8 ou 9 chiffres.'))
# def clean_mobile(self):
# if self.cleaned_data['mobile'] is None:
# return None
# elif self._test_phone(self.cleaned_data['mobile']):
# return self.set_32(self.cleaned_data['mobile'])
# else:
# raise ValidationError(_('Respecter le format: (+32 ou 0) \
# suivi de 8 ou 9 chiffres.'))
def clean_cgu(self):
if self.cleaned_data['cgu']:
......
......@@ -591,7 +591,7 @@ class UserGeneric(models.Model):
"""
User always in working tables tables (IN & OUT)
"""
profile = models.ForeignKey(Profile, on_delete=models.CASCADE)
profile = models.ForeignKey(User, on_delete=models.CASCADE)
class Meta:
abstract = True
......
......@@ -61,7 +61,7 @@
<td><a href="{% url 'profile_activate' profile.id %}">{{ profile.username }}</a></td>
<td>{{ profile.date_joined|date:"d/m/Y" }}</td>
<td>{{ profile.last_login|date:"d/m/Y" }}</td>
<td>{{ profile.jlastlog }} jours</td>
<td>{{ profile.jlastlog }} {{ jours }}</td>
<td>{% if profile.email_confirmed %}OUI{% else %}NON{% endif %}</td>
<td>
{% if profile.is_active %}
......
......@@ -28,7 +28,7 @@ from django.utils.encoding import force_bytes, force_text
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.utils.translation import ugettext as _
# Accounts App
from config.settings import PASSWORD_RESET_TIMEOUT_DAYS, LOGIN_REDIRECT_URL
from config.settings import PASSWORD_RESET_TIMEOUT_DAYS, LOGIN_REDIRECT_URL, DATABASES
from .tokens import account_activation_token
from .forms import ProfileUpdateForm, ProfileSignUpForm, ProfileSearchForm, MyAuthenticationForm
......@@ -195,8 +195,10 @@ class MyLoginRequiredMixin(LoginRequiredMixin):
class ProfileList(MyLoginRequiredMixin, ListView):
model = get_user_model()
title = "Mes utilisateurs"
template_name = "accounts/profile_list.html"
form = ProfileSearchForm(None)
modeltxt = "User"
jours = ""
# paginate_by = 100
def get(self, request, *args, **kwargs):
......@@ -251,13 +253,25 @@ class ProfileList(MyLoginRequiredMixin, ListView):
qs = self.model.objects.filter(support_structure__exact=struct_id)
qs = qs.exclude(id=self.request.user.id)
qsf = qs.filter(self.build_where(param=self.request.GET))
qsf = qsf.annotate(lastlog=TruncDate(Coalesce('last_login', timezone.now())))
qsf = qsf.annotate(jlastlog=date.today() - F('lastlog'))
if 'postgresql' in DATABASES['default']['ENGINE']:
qsf = qsf.annotate(lastlog=TruncDate(Coalesce('last_login', timezone.now())))
qsf = qsf.annotate(jlastlog=date.today() - F('lastlog'))
else:
qsf = qsf.annotate(jlastlog=F('last_login'))
return qsf
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if 'postgresql' in DATABASES['default']['ENGINE']:
context['jours'] = 'jours'
else:
context['jours'] = ''
return context
class ProfileDetailView(MyLoginRequiredMixin, DetailView):
model = get_user_model()
template_name = "accounts/profile_detail.html"
manager_mobile = []
manager_phone = []
context = {}
......@@ -295,6 +309,7 @@ class ProfileDetailView(MyLoginRequiredMixin, DetailView):
class ProfileUpdateView(MyLoginRequiredMixin, MessageMixin, UpdateView):
model = get_user_model()
template_name = "accounts/profile_form.html"
form_class = ProfileUpdateForm
def get_form_kwargs(self):
......@@ -309,7 +324,7 @@ class ProfileDeleteView(MyLoginRequiredMixin, MessageMixin, DeleteView):
"""User Delete"""
model = get_user_model()
# obligatoire sinon django pointe sur modelname_confirm_delete.html
template_name = "accounts/user_detail.html"
template_name = "accounts/profile_detail.html"
success_url = reverse_lazy("profile_list")
confirm_message = _("Supprimer cet utilisateur?")
......@@ -351,7 +366,7 @@ class MyLoginView(LoginView):
class ProfileActivateView(MyLoginRequiredMixin, UpdateView):
model = get_user_model()
fields = ["is_active"]
template_name = "accounts/user_activate.html"
template_name = "accounts/profile_activate.html"
success_url = "profile_list"
action = _("Activer")
......
......@@ -5,7 +5,7 @@ Shell script to be stored in source django folder
This script adapt accounts.models.py file from User to Profile
----------------------------------------------------------------
Author: Patrick Houben
Date: 17/10/2018
Date: 24/06/2020
----------------------------------------------------------------
COMMENT1
......
......@@ -89,6 +89,7 @@ PRIVATE_PGP_KEY_PATH = os.path.abspath(os.path.join(BASE_DIR, PRI_KEY_PATH))
PUBLIC_PGP_KEY = open(PUBLIC_PGP_KEY_PATH).read()
PRIVATE_PGP_KEY = open(PRIVATE_PGP_KEY_PATH).read()
if SERVER_NAME == "pythonprod":
ALLOWED_HOSTS = get_local_setting('ALLOWED_HOSTS')
DATABASES = get_local_setting("DATABASES")
......
......@@ -18,10 +18,10 @@
"MEDIA_ROOT": "/var/www/tresoferme/media",
"EMAIL_HOST": "smtp.gmail.com",
"EMAIL_PORT": "587",
"EMAIL_HOST_USER": "your_account@gmail.com",
"EMAIL_HOST_PASSWORD": "your passwd",
"DEFAULT_FROM_EMAIL": "TresoFerme <tresoferme@cra.wallonie.be>",
"REQUEST_IGNORE_USERNAME": ["admin", "mike"],
"EMAIL_HOST_USER": "hello@google.be",
"EMAIL_HOST_PASSWORD": "mybestpasswd",
"DEFAULT_FROM_EMAIL": "TresoFerme <tresoferme@cra.wallonie.be>",
"REQUEST_IGNORE_USERNAME": ["admin", "manager"],
"REQUEST_VALID_METHOD_NAMES": ["get"],
"REDIS_PASSWD" : "Mypasswd"
}
......@@ -17,14 +17,14 @@ __status__ = 'Development'
# https://stackoverflow.com/questions/22918095/django-string-to-date-format
def parse_date(date_str):
"""Parse date from string by DATE_INPUT_FORMATS of current language"""
for item in get_format('DATE_INPUT_FORMATS'):
try:
return datetime.strptime(date_str, item).date()
except (ValueError, TypeError):
continue
return None
# def parse_date(date_str):
# """Parse date from string by DATE_INPUT_FORMATS of current language"""
# for item in get_format('DATE_INPUT_FORMATS'):
# try:
# return datetime.strptime(date_str, item).date()
# except (ValueError, TypeError):
# continue
# return None
def build_error_message(cause, error, user):
......
......@@ -60,7 +60,14 @@
<td>
<p>Mineur: Ajout source GitRural en bas de page</p>
</td>
</tr>
</tr>
<tr>
<td>1.4.1</td>
<td>26/06/2020</td>
<td>
<p>Majeur: Adaptations pour installation en local avec base de données SQLite</p>
</td>
</tr>
</tbody>
......