Commit 660a3161 authored by Sli's avatar Sli
Browse files

Merge branch 'new_django' into 'master'

upgrade to django 2.2

See merge request !243
parents 9e6c4b32 c3f2d0a1
Pipeline #2089 failed with stage
in 60 minutes and 7 seconds
......@@ -4,6 +4,7 @@ from __future__ import unicode_literals
from django.db import migrations, models
import django.core.validators
import accounting.models
import django.db.models.deletion
class Migration(migrations.Migration):
......@@ -243,6 +244,7 @@ class Migration(migrations.Migration):
verbose_name="accounting type",
to="accounting.AccountingType",
blank=True,
on_delete=django.db.models.deletion.CASCADE,
),
),
],
......@@ -267,6 +269,7 @@ class Migration(migrations.Migration):
verbose_name="simplified accounting types",
to="accounting.AccountingType",
related_name="simplified_types",
on_delete=django.db.models.deletion.CASCADE,
),
),
],
......
......@@ -2,6 +2,7 @@
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
......@@ -22,6 +23,7 @@ class Migration(migrations.Migration):
verbose_name="invoice",
to="core.SithFile",
blank=True,
on_delete=django.db.models.deletion.CASCADE,
),
),
migrations.AddField(
......@@ -31,12 +33,14 @@ class Migration(migrations.Migration):
verbose_name="journal",
to="accounting.GeneralJournal",
related_name="operations",
on_delete=django.db.models.deletion.CASCADE,
),
),
migrations.AddField(
model_name="operation",
name="linked_operation",
field=models.OneToOneField(
on_delete=django.db.models.deletion.CASCADE,
blank=True,
to="accounting.Operation",
null=True,
......@@ -54,6 +58,7 @@ class Migration(migrations.Migration):
verbose_name="simple type",
to="accounting.SimplifiedAccountingType",
blank=True,
on_delete=django.db.models.deletion.CASCADE,
),
),
migrations.AddField(
......@@ -63,6 +68,7 @@ class Migration(migrations.Migration):
verbose_name="club account",
to="accounting.ClubAccount",
related_name="journals",
on_delete=django.db.models.deletion.CASCADE,
),
),
migrations.AddField(
......@@ -72,20 +78,27 @@ class Migration(migrations.Migration):
verbose_name="bank account",
to="accounting.BankAccount",
related_name="club_accounts",
on_delete=django.db.models.deletion.CASCADE,
),
),
migrations.AddField(
model_name="clubaccount",
name="club",
field=models.ForeignKey(
verbose_name="club", to="club.Club", related_name="club_account"
verbose_name="club",
to="club.Club",
related_name="club_account",
on_delete=django.db.models.deletion.CASCADE,
),
),
migrations.AddField(
model_name="bankaccount",
name="club",
field=models.ForeignKey(
verbose_name="club", to="club.Club", related_name="bank_accounts"
verbose_name="club",
to="club.Club",
related_name="bank_accounts",
on_delete=django.db.models.deletion.CASCADE,
),
),
migrations.AlterUniqueTogether(
......
......@@ -29,6 +29,7 @@ class Migration(migrations.Migration):
related_name="labels",
verbose_name="club account",
to="accounting.ClubAccount",
on_delete=django.db.models.deletion.CASCADE,
),
),
],
......
......@@ -22,7 +22,7 @@
#
#
from django.core.urlresolvers import reverse
from django.urls import reverse
from django.core.exceptions import ValidationError
from django.core import validators
from django.db import models
......@@ -110,7 +110,12 @@ class BankAccount(models.Model):
name = models.CharField(_("name"), max_length=30)
iban = models.CharField(_("iban"), max_length=255, blank=True)
number = models.CharField(_("account number"), max_length=255, blank=True)
club = models.ForeignKey(Club, related_name="bank_accounts", verbose_name=_("club"))
club = models.ForeignKey(
Club,
related_name="bank_accounts",
verbose_name=_("club"),
on_delete=models.CASCADE,
)
class Meta:
verbose_name = _("Bank account")
......@@ -136,9 +141,17 @@ class BankAccount(models.Model):
class ClubAccount(models.Model):
name = models.CharField(_("name"), max_length=30)
club = models.ForeignKey(Club, related_name="club_account", verbose_name=_("club"))
club = models.ForeignKey(
Club,
related_name="club_account",
verbose_name=_("club"),
on_delete=models.CASCADE,
)
bank_account = models.ForeignKey(
BankAccount, related_name="club_accounts", verbose_name=_("bank account")
BankAccount,
related_name="club_accounts",
verbose_name=_("bank account"),
on_delete=models.CASCADE,
)
class Meta:
......@@ -203,7 +216,11 @@ class GeneralJournal(models.Model):
name = models.CharField(_("name"), max_length=40)
closed = models.BooleanField(_("is closed"), default=False)
club_account = models.ForeignKey(
ClubAccount, related_name="journals", null=False, verbose_name=_("club account")
ClubAccount,
related_name="journals",
null=False,
verbose_name=_("club account"),
on_delete=models.CASCADE,
)
amount = CurrencyField(_("amount"), default=0)
effective_amount = CurrencyField(_("effective_amount"), default=0)
......@@ -263,7 +280,11 @@ class Operation(models.Model):
number = models.IntegerField(_("number"))
journal = models.ForeignKey(
GeneralJournal, related_name="operations", null=False, verbose_name=_("journal")
GeneralJournal,
related_name="operations",
null=False,
verbose_name=_("journal"),
on_delete=models.CASCADE,
)
amount = CurrencyField(_("amount"))
date = models.DateField(_("date"))
......@@ -282,6 +303,7 @@ class Operation(models.Model):
verbose_name=_("invoice"),
null=True,
blank=True,
on_delete=models.CASCADE,
)
done = models.BooleanField(_("is done"), default=False)
simpleaccounting_type = models.ForeignKey(
......@@ -290,6 +312,7 @@ class Operation(models.Model):
verbose_name=_("simple type"),
null=True,
blank=True,
on_delete=models.CASCADE,
)
accounting_type = models.ForeignKey(
"AccountingType",
......@@ -297,6 +320,7 @@ class Operation(models.Model):
verbose_name=_("accounting type"),
null=True,
blank=True,
on_delete=models.CASCADE,
)
label = models.ForeignKey(
"Label",
......@@ -328,6 +352,7 @@ class Operation(models.Model):
null=True,
blank=True,
default=None,
on_delete=models.CASCADE,
)
class Meta:
......@@ -487,6 +512,7 @@ class SimplifiedAccountingType(models.Model):
AccountingType,
related_name="simplified_types",
verbose_name=_("simplified accounting types"),
on_delete=models.CASCADE,
)
class Meta:
......@@ -518,7 +544,10 @@ class Label(models.Model):
name = models.CharField(_("label"), max_length=64)
club_account = models.ForeignKey(
ClubAccount, related_name="labels", verbose_name=_("club account")
ClubAccount,
related_name="labels",
verbose_name=_("club account"),
on_delete=models.CASCADE,
)
class Meta:
......
......@@ -20,14 +20,14 @@
{% for k,v in statement.items() %}
<tr>
<td>{{ k }}</td>
<td>{{ v }}</td>
<td>{{ "%.2f" % v }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<p><strong>{% trans %}Amount: {% endtrans %}</strong>{{ object.amount }}</p>
<p><strong>{% trans %}Effective amount: {% endtrans %}</strong>{{ object.effective_amount }}</p>
<p><strong>{% trans %}Amount: {% endtrans %}</strong>{{ "%.2f" % object.amount }}</p>
<p><strong>{% trans %}Effective amount: {% endtrans %}</strong>{{ "%.2f" %object.effective_amount }}</p>
</div>
{% endblock %}
......@@ -18,12 +18,12 @@
{% for k,v in dict['CREDIT'].items() %}
<tr>
<td>{{ k }}</td>
<td>{{ v }}</td>
<td>{{ "%.2f" % v }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% trans %}Total: {% endtrans %}{{ dict['CREDIT_sum'] }}
{% trans %}Total: {% endtrans %}{{ "%.2f" % dict['CREDIT_sum'] }}
<h6>{% trans %}Debit{% endtrans %}</h6>
<table>
......@@ -37,19 +37,19 @@
{% for k,v in dict['DEBIT'].items() %}
<tr>
<td>{{ k }}</td>
<td>{{ v }}</td>
<td>{{ "%.2f" % v }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% trans %}Total: {% endtrans %}{{ dict['DEBIT_sum'] }}
{% trans %}Total: {% endtrans %}{{ "%.2f" % dict['DEBIT_sum'] }}
{% endmacro %}
{% block content %}
<h3>{% trans %}Statement by nature: {% endtrans %} {{ object.name }}</h3>
{% for k,v in statement.items() %}
<h4 style="background: lightblue; padding: 4px;">{{ k }} : {{ v['CREDIT_sum'] - v['DEBIT_sum'] }}</h4>
<h4 style="background: lightblue; padding: 4px;">{{ k }} : {{ "%.2f" % (v['CREDIT_sum'] - v['DEBIT_sum']) }}</h4>
{{ display_tables(v) }}
<hr>
{% endfor %}
......
......@@ -28,14 +28,14 @@
{% else %}
<td></td>
{% endif %}
<td>{{ credit_statement[key] }}</td>
<td>{{ "%.2f" % credit_statement[key] }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<p>Total : {{ total_credit }}</p>
<p>Total : {{ "%.2f" % total_credit }}</p>
<h4>{% trans %}Debit{% endtrans %}</h4>
......@@ -56,13 +56,13 @@
{% else %}
<td></td>
{% endif %}
<td>{{ debit_statement[key] }}</td>
<td>{{ "%.2f" % debit_statement[key] }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<p>Total : {{ total_debit }}</p>
<p>Total : {{ "%.2f" % total_debit }}</p>
</div>
{% endblock %}
......@@ -23,7 +23,7 @@
#
from django.test import TestCase
from django.core.urlresolvers import reverse
from django.urls import reverse
from django.core.management import call_command
from datetime import date
......@@ -272,30 +272,50 @@ class OperationTest(TestCase):
def test_nature_statement(self):
self.client.login(username="comptable", password="plop")
response_get = self.client.get(
response = self.client.get(
reverse("accounting:journal_nature_statement", args=[self.journal.id])
)
self.assertTrue(
"bob (Troll Pench\\xc3\\xa9) : 3.00" in str(response_get.content)
)
self.assertContains(response, "bob (Troll Penché) : 3.00", status_code=200)
def test_person_statement(self):
self.client.login(username="comptable", password="plop")
response_get = self.client.get(
response = self.client.get(
reverse("accounting:journal_person_statement", args=[self.journal.id])
)
self.assertTrue(
"<td>3.00</td>" in str(response_get.content)
and '<td><a href="/user/1/">S&#39; Kia</a></td>'
in str(response_get.content)
self.assertContains(response, "Total : 5575.72", status_code=200)
self.assertContains(response, "Total : 71.42")
self.assertContains(
response,
"""
<td><a href="/user/1/">S&#39; Kia</a></td>
<td>3.00</td>""",
)
self.assertContains(
response,
"""
<td><a href="/user/1/">S&#39; Kia</a></td>
<td>823.00</td>""",
)
def test_accounting_statement(self):
self.client.login(username="comptable", password="plop")
response_get = self.client.get(
response = self.client.get(
reverse("accounting:journal_accounting_statement", args=[self.journal.id])
)
self.assertTrue(
"<td>443 - Cr\\xc3\\xa9dit - Ce code n&#39;existe pas</td>"
in str(response_get.content)
self.assertContains(
response,
"""
<tr>
<td>443 - Crédit - Ce code n&#39;existe pas</td>
<td>3.00</td>
</tr>""",
status_code=200,
)
self.assertContains(
response,
"""
<p><strong>Montant : </strong>-5504.30 €</p>
<p><strong>Montant effectif: </strong>-5504.30 €</p>""",
)
......@@ -22,131 +22,133 @@
#
#
from django.conf.urls import url
from django.urls import re_path
from accounting.views import *
urlpatterns = [
# Accounting types
url(
re_path(
r"^simple_type$",
SimplifiedAccountingTypeListView.as_view(),
name="simple_type_list",
),
url(
re_path(
r"^simple_type/create$",
SimplifiedAccountingTypeCreateView.as_view(),
name="simple_type_new",
),
url(
re_path(
r"^simple_type/(?P<type_id>[0-9]+)/edit$",
SimplifiedAccountingTypeEditView.as_view(),
name="simple_type_edit",
),
# Accounting types
url(r"^type$", AccountingTypeListView.as_view(), name="type_list"),
url(r"^type/create$", AccountingTypeCreateView.as_view(), name="type_new"),
url(
re_path(r"^type$", AccountingTypeListView.as_view(), name="type_list"),
re_path(r"^type/create$", AccountingTypeCreateView.as_view(), name="type_new"),
re_path(
r"^type/(?P<type_id>[0-9]+)/edit$",
AccountingTypeEditView.as_view(),
name="type_edit",
),
# Bank accounts
url(r"^$", BankAccountListView.as_view(), name="bank_list"),
url(r"^bank/create$", BankAccountCreateView.as_view(), name="bank_new"),
url(
re_path(r"^$", BankAccountListView.as_view(), name="bank_list"),
re_path(r"^bank/create$", BankAccountCreateView.as_view(), name="bank_new"),
re_path(
r"^bank/(?P<b_account_id>[0-9]+)$",
BankAccountDetailView.as_view(),
name="bank_details",
),
url(
re_path(
r"^bank/(?P<b_account_id>[0-9]+)/edit$",
BankAccountEditView.as_view(),
name="bank_edit",
),
url(
re_path(
r"^bank/(?P<b_account_id>[0-9]+)/delete$",
BankAccountDeleteView.as_view(),
name="bank_delete",
),
# Club accounts
url(r"^club/create$", ClubAccountCreateView.as_view(), name="club_new"),
url(
re_path(r"^club/create$", ClubAccountCreateView.as_view(), name="club_new"),
re_path(
r"^club/(?P<c_account_id>[0-9]+)$",
ClubAccountDetailView.as_view(),
name="club_details",
),
url(
re_path(
r"^club/(?P<c_account_id>[0-9]+)/edit$",
ClubAccountEditView.as_view(),
name="club_edit",
),
url(
re_path(
r"^club/(?P<c_account_id>[0-9]+)/delete$",
ClubAccountDeleteView.as_view(),
name="club_delete",
),
# Journals
url(r"^journal/create$", JournalCreateView.as_view(), name="journal_new"),
url(
re_path(r"^journal/create$", JournalCreateView.as_view(), name="journal_new"),
re_path(
r"^journal/(?P<j_id>[0-9]+)$",
JournalDetailView.as_view(),
name="journal_details",
),
url(
re_path(
r"^journal/(?P<j_id>[0-9]+)/edit$",
JournalEditView.as_view(),
name="journal_edit",
),
url(
re_path(
r"^journal/(?P<j_id>[0-9]+)/delete$",
JournalDeleteView.as_view(),
name="journal_delete",
),
url(
re_path(
r"^journal/(?P<j_id>[0-9]+)/statement/nature$",
JournalNatureStatementView.as_view(),
name="journal_nature_statement",
),
url(
re_path(
r"^journal/(?P<j_id>[0-9]+)/statement/person$",
JournalPersonStatementView.as_view(),
name="journal_person_statement",
),
url(
re_path(
r"^journal/(?P<j_id>[0-9]+)/statement/accounting$",
JournalAccountingStatementView.as_view(),
name="journal_accounting_statement",
),
# Operations
url(
re_path(
r"^operation/create/(?P<j_id>[0-9]+)$",
OperationCreateView.as_view(),
name="op_new",
),
url(r"^operation/(?P<op_id>[0-9]+)$", OperationEditView.as_view(), name="op_edit"),
url(
re_path(
r"^operation/(?P<op_id>[0-9]+)$", OperationEditView.as_view(), name="op_edit"
),
re_path(
r"^operation/(?P<op_id>[0-9]+)/pdf$", OperationPDFView.as_view(), name="op_pdf"
),
# Companies
url(r"^company/list$", CompanyListView.as_view(), name="co_list"),
url(r"^company/create$", CompanyCreateView.as_view(), name="co_new"),
url(r"^company/(?P<co_id>[0-9]+)$", CompanyEditView.as_view(), name="co_edit"),
re_path(r"^company/list$", CompanyListView.as_view(), name="co_list"),
re_path(r"^company/create$", CompanyCreateView.as_view(), name="co_new"),
re_path(r"^company/(?P<co_id>[0-9]+)$", CompanyEditView.as_view(), name="co_edit"),
# Labels
url(r"^label/new$", LabelCreateView.as_view(), name="label_new"),
url(
re_path(r"^label/new$", LabelCreateView.as_view(), name="label_new"),
re_path(
r"^label/(?P<clubaccount_id>[0-9]+)$",
LabelListView.as_view(),
name="label_list",
),
url(
re_path(
r"^label/(?P<label_id>[0-9]+)/edit$", LabelEditView.as_view(), name="label_edit"
),
url(
re_path(
r"^label/(?P<label_id>[0-9]+)/delete$",
LabelDeleteView.as_view(),
name="label_delete",
),
# User account
url(r"^refound/account$", RefoundAccountView.as_view(), name="refound_account"),
re_path(r"^refound/account$", RefoundAccountView.as_view(), name="refound_account"),
]
......@@ -24,7 +24,7 @@
from django.views.generic import ListView, DetailView
from django.views.generic.edit import UpdateView, CreateView, DeleteView, FormView
from django.core.urlresolvers import reverse_lazy, reverse
from django.urls import reverse_lazy, reverse
from django.utils.translation import ugettext_lazy as _
from django.forms.models import modelform_factory
from django.core.exceptions import PermissionDenied, ValidationError
......
......@@ -22,35 +22,35 @@
#
#
from django.conf.urls import url, include
from django.urls import re_path, include
from api.views import *
from rest_framework import routers
# Router config
router = routers.DefaultRouter()
router.register(r"counter", CounterViewSet, base_name="api_counter")
router.register(r"user", UserViewSet, base_name="api_user")
router.register(r"club", ClubViewSet, base_name="api_club")
router.register(r"group", GroupViewSet, base_name="api_group")
router.register(r"counter", CounterViewSet, basename="api_counter")
router.register(r"user", UserViewSet, basename="api_user")
router.register(r"club", ClubViewSet, basename="api_club")
router.register(r"group", GroupViewSet, basename="api_group")
# Launderette
router.register(
r"launderette/place", LaunderettePlaceViewSet, base_name="api_launderette_place"
r"launderette/place", LaunderettePlaceViewSet, basename="api_launderette_place"
)
router.register(
r"launderette/machine",
LaunderetteMachineViewSet,
base_name="api_launderette_machine",
basename="api_launderette_machine",
)
router.register(
r"launderette/token", LaunderetteTokenViewSet, base_name="api_launderette_token"
r"launderette/token", LaunderetteTokenViewSet, basename="api_launderette_token"
)
urlpatterns = [
# API
url(r"^", include(router.urls)),
url(r"^login/", include("rest_framework.urls", namespace="rest_framework")),
url(r"^markdown$", RenderMarkdown, name="api_markdown"),
url(r"^mailings$", FetchMailingLists, name="mailings_fetch"),
re_path(r"^", include(router.urls)),
re_path(r"^login/", include("rest_framework.urls", namespace="rest_framework")),
re_path(r"^markdown$", RenderMarkdown, name="api_markdown"),