Added views for invoices
Added class-based views for all operations Added corresponding urls Updated transaction page to use new views
This commit is contained in:
parent
d8c95fac25
commit
033698b38a
9 changed files with 168 additions and 51 deletions
Binary file not shown.
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: 0.0.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-12-28 10:16+0100\n"
|
||||
"POT-Creation-Date: 2022-12-28 11:47+0100\n"
|
||||
"PO-Revision-Date: 2022-12-21 17:30+0100\n"
|
||||
"Last-Translator: edpibu <git@edgarpierre.fr>\n"
|
||||
"Language-Team: edpibu <git@edgarpierre.fr>\n"
|
||||
|
@ -23,8 +23,9 @@ msgstr ""
|
|||
msgid "Category"
|
||||
msgstr "Catégorie"
|
||||
|
||||
#: .\main\models.py:16 .\main\models.py:41 .\main\models.py:107
|
||||
#: .\main\models.py:16 .\main\models.py:41 .\main\models.py:114
|
||||
#: .\main\templates\main\tag\transaction_table.html:7
|
||||
#: .\main\templates\main\transaction_form.html:27
|
||||
msgid "Name"
|
||||
msgstr "Nom"
|
||||
|
||||
|
@ -41,7 +42,7 @@ msgstr "Budget"
|
|||
msgid "Categories"
|
||||
msgstr "Catégories"
|
||||
|
||||
#: .\main\models.py:41 .\main\models.py:79 .\main\templates\main\base.html:39
|
||||
#: .\main\models.py:41 .\main\models.py:86 .\main\templates\main\base.html:39
|
||||
msgid "Transaction"
|
||||
msgstr "Transaction"
|
||||
|
||||
|
@ -49,12 +50,12 @@ msgstr "Transaction"
|
|||
msgid "Description"
|
||||
msgstr "Description"
|
||||
|
||||
#: .\main\models.py:45 .\main\models.py:146 .\main\templates\main\index.html:40
|
||||
#: .\main\models.py:45 .\main\models.py:169 .\main\templates\main\index.html:40
|
||||
#: .\main\templates\main\tag\transaction_table.html:8
|
||||
msgid "Value"
|
||||
msgstr "Valeur"
|
||||
|
||||
#: .\main\models.py:47 .\main\models.py:144 .\main\templates\main\index.html:39
|
||||
#: .\main\models.py:47 .\main\models.py:167 .\main\templates\main\index.html:39
|
||||
#: .\main\templates\main\tag\transaction_table.html:6
|
||||
msgid "Date"
|
||||
msgstr "Date"
|
||||
|
@ -71,35 +72,35 @@ msgstr "Commerçant"
|
|||
msgid "Payment"
|
||||
msgstr "Paiement"
|
||||
|
||||
#: .\main\models.py:80 .\main\templates\main\category.html:26
|
||||
#: .\main\models.py:87 .\main\templates\main\category.html:26
|
||||
#: .\main\templates\main\index.html:17 .\main\templates\main\index.html:42
|
||||
#: .\main\templates\main\snapshot.html:78
|
||||
#: .\main\templates\main\transactions.html:15
|
||||
msgid "Transactions"
|
||||
msgstr "Transactions"
|
||||
|
||||
#: .\main\models.py:107 .\main\models.py:125
|
||||
#: .\main\models.py:114 .\main\models.py:148
|
||||
msgid "Invoice"
|
||||
msgstr "Facture"
|
||||
|
||||
#: .\main\models.py:112 .\main\models.py:157
|
||||
#: .\main\models.py:119 .\main\models.py:180
|
||||
msgid "File"
|
||||
msgstr "Fichier"
|
||||
|
||||
#: .\main\models.py:126
|
||||
#: .\main\models.py:149 .\main\templates\main\transaction_form.html:23
|
||||
msgid "Invoices"
|
||||
msgstr "Factures"
|
||||
|
||||
#: .\main\models.py:163
|
||||
#: .\main\models.py:186
|
||||
#, python-format
|
||||
msgid "%(date)s snapshot"
|
||||
msgstr "Relevé du %(date)s"
|
||||
|
||||
#: .\main\models.py:265 .\main\templates\main\base.html:49
|
||||
#: .\main\models.py:288 .\main\templates\main\base.html:49
|
||||
msgid "Snapshot"
|
||||
msgstr "Relevé"
|
||||
|
||||
#: .\main\models.py:266 .\main\templates\main\index.html:35
|
||||
#: .\main\models.py:289 .\main\templates\main\index.html:35
|
||||
msgid "Snapshots"
|
||||
msgstr "Relevés"
|
||||
|
||||
|
@ -113,8 +114,8 @@ msgstr "Se déconnecter"
|
|||
|
||||
#: .\main\templates\main\confirm_delete.html:19
|
||||
#, python-format
|
||||
msgid "Are you sure you want do delete <%(object)s> ?"
|
||||
msgstr "Êtes-vous sûr de vouloir supprimer <%(object)s> ?"
|
||||
msgid "Are you sure you want do delete <strong>%(object)s</strong> ?"
|
||||
msgstr "Êtes-vous sûr de vouloir supprimer <strong>%(object)s</strong> ?"
|
||||
|
||||
#: .\main\templates\main\confirm_delete.html:23
|
||||
msgid "Cancel"
|
||||
|
@ -124,6 +125,17 @@ msgstr "Annuler"
|
|||
msgid "Confirm"
|
||||
msgstr "Confirmer"
|
||||
|
||||
#: .\main\templates\main\form\base.html:17
|
||||
#: .\main\templates\main\tag\form_buttons.html:4
|
||||
#: .\main\templates\main\transaction_form.html:34
|
||||
msgid "Delete"
|
||||
msgstr "Supprimer"
|
||||
|
||||
#: .\main\templates\main\form\base.html:20
|
||||
#: .\main\templates\main\tag\form_buttons.html:8
|
||||
msgid "Save"
|
||||
msgstr "Enregistrer"
|
||||
|
||||
#: .\main\templates\main\index.html:41
|
||||
msgid "Difference"
|
||||
msgstr "Différence"
|
||||
|
@ -136,16 +148,6 @@ msgstr "Valide"
|
|||
msgid "Log In"
|
||||
msgstr "Se connecter"
|
||||
|
||||
#: .\main\templates\main\tag\form_buttons.html:4
|
||||
msgid "Delete"
|
||||
msgstr "Supprimer"
|
||||
|
||||
#: .\main\templates\main\tag\form_buttons.html:8
|
||||
msgid "Save"
|
||||
msgstr "Enregistrer"
|
||||
|
||||
#~ msgid "Add invoice"
|
||||
#~ msgstr "Ajouter une facture"
|
||||
|
||||
#~ msgid "Add"
|
||||
#~ msgstr "Ajouter"
|
||||
#: .\main\templates\main\transaction_form.html:39
|
||||
msgid "New invoice"
|
||||
msgstr "Nouvelle facture"
|
||||
|
|
|
@ -66,6 +66,13 @@ class Transaction(models.Model):
|
|||
def get_absolute_url(self):
|
||||
return reverse("transaction", kwargs={"pk": self.pk})
|
||||
|
||||
def get_delete_url(self):
|
||||
return reverse("del_transaction", kwargs={"pk": self.pk})
|
||||
|
||||
@property
|
||||
def adding(self):
|
||||
return self._state.adding
|
||||
|
||||
@property
|
||||
def invoices(self):
|
||||
return Invoice.objects.filter(transaction=self)
|
||||
|
@ -112,15 +119,33 @@ class Invoice(models.Model):
|
|||
verbose_name=_("File"),
|
||||
max_length=128,
|
||||
)
|
||||
transaction = models.ForeignKey(Transaction, on_delete=models.CASCADE)
|
||||
transaction = models.ForeignKey(
|
||||
Transaction, on_delete=models.CASCADE, editable=False
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.name}: {self.transaction}"
|
||||
if hasattr(self, "transaction"):
|
||||
return f"{self.name} – {self.transaction.name}"
|
||||
return self.name
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
self.file.delete()
|
||||
super().delete(*args, **kwargs)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse(
|
||||
"invoice", kwargs={"transaction_pk": self.transaction.pk, "pk": self.pk}
|
||||
)
|
||||
|
||||
def get_delete_url(self):
|
||||
return reverse(
|
||||
"del_invoice", kwargs={"transaction_pk": self.transaction.pk, "pk": self.pk}
|
||||
)
|
||||
|
||||
@property
|
||||
def adding(self):
|
||||
return self._state.adding
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("Invoice")
|
||||
verbose_name_plural = _("Invoices")
|
||||
|
@ -132,7 +157,7 @@ class InvoiceForm(ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = Invoice
|
||||
fields = ["name", "file"]
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
def snapshot_path(instance, filename):
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<p>
|
||||
{% blocktranslate %}Are you sure you want do delete <{{ object }}> ?{% endblocktranslate %}
|
||||
{% blocktranslate %}Are you sure you want do delete <strong>{{ object }}</strong> ?{% endblocktranslate %}
|
||||
</p>
|
||||
{{ form }}
|
||||
<div class="buttons">
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
{% load i18n %}
|
||||
{% block fields %}
|
||||
{% csrf_token %}
|
||||
{% if form.non_field_errors %}
|
||||
<ul class='errorlist'>
|
||||
{% for error in form.non_field_errors %}<li>{{ error }}</li>{% endfor %}
|
||||
|
@ -12,3 +11,12 @@
|
|||
<div>{{ field }}</div>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
{% block buttons %}
|
||||
<div class="buttons">
|
||||
{% if not form.instance.adding %}
|
||||
<a class="btn del" href="{{ form.instance.get_delete_url }}">{% translate "Delete" %}</a>
|
||||
{% endif %}
|
||||
<input type="reset" />
|
||||
<input type="submit" value="{% translate 'Save' %}" />
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
22
nummi/main/templates/main/invoice_form.html
Normal file
22
nummi/main/templates/main/invoice_form.html
Normal file
|
@ -0,0 +1,22 @@
|
|||
{% extends "main/base.html" %}
|
||||
{% load static %}
|
||||
{% load main_extras %}
|
||||
{% load i18n %}
|
||||
{% block link %}
|
||||
{{ block.super }}
|
||||
<link rel="stylesheet"
|
||||
href="{% static 'main/css/form.css' %}"
|
||||
type="text/css"/>
|
||||
<link rel="stylesheet"
|
||||
href="{% static 'main/css/table.css' %}"
|
||||
type="text/css"/>
|
||||
{% endblock %}
|
||||
{% block body %}
|
||||
<h1>{{ form.instance }}</h1>
|
||||
{% spaceless %}
|
||||
<form id="transaction" method="post" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
{{ form }}
|
||||
</form>
|
||||
{% endspaceless %}
|
||||
{% endblock %}
|
|
@ -12,11 +12,32 @@
|
|||
type="text/css"/>
|
||||
{% endblock %}
|
||||
{% block body %}
|
||||
<h1>{{ transaction }}</h1>
|
||||
<h1>{{ form.instance }}</h1>
|
||||
{% spaceless %}
|
||||
<form id="transaction" action="" method="post">
|
||||
<form id="transaction" method="post">
|
||||
{% csrf_token %}
|
||||
{{ form }}
|
||||
{% form_buttons form.instance %}
|
||||
</form>
|
||||
{% endspaceless %}
|
||||
{% if not form.instance.adding %}
|
||||
<h2>{% translate "Invoices" %}</h2>
|
||||
<div id="invoices" class="table col1-1-1">
|
||||
<div class="header">
|
||||
<strong class="attach center"><i class="fa fa-file"></i></strong>
|
||||
<strong class="name">{% translate "Name" %}</strong>
|
||||
<strong class="attach right"><i class="fa fa-trash-can"></i></strong>
|
||||
</div>
|
||||
{% for inv in transaction.invoices %}
|
||||
<div class="invoice">
|
||||
<a href="{{ inv.file.url }}"><i class="fa-regular fa-file"></i></a>
|
||||
<a href="{{ inv.get_absolute_url }}">{{ inv.name }}</a>
|
||||
<a href="{{ inv.get_delete_url }}" class="right">{% translate "Delete" %}</a>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div class="invoice new">
|
||||
<i class="fa fa-file-circle-plus"></i>
|
||||
<a href="{% url "invoice" transaction.pk %}">{% translate "New invoice" %}</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -8,14 +8,27 @@ urlpatterns = [
|
|||
path("logout", views.LogoutView.as_view(), name="logout"),
|
||||
path("transactions", views.TransactionListView.as_view(), name="transactions"),
|
||||
path("transaction", views.TransactionCreateView.as_view(), name="transaction"),
|
||||
path(
|
||||
"transaction/<transaction_pk>/invoice",
|
||||
views.InvoiceCreateView.as_view(),
|
||||
name="invoice",
|
||||
),
|
||||
path("transaction/<pk>", views.TransactionUpdateView.as_view(), name="transaction"),
|
||||
path(
|
||||
"transaction/delete/<pk>",
|
||||
"transaction/<transaction_pk>/invoice/<pk>",
|
||||
views.InvoiceUpdateView.as_view(),
|
||||
name="invoice",
|
||||
),
|
||||
path(
|
||||
"transaction/<pk>/delete",
|
||||
views.TransactionDeleteView.as_view(),
|
||||
name="del_transaction",
|
||||
),
|
||||
path("del_invoice/<uuid>/<invoice_id>", views.del_invoice, name="del_invoice"),
|
||||
path("invoice/<uuid>", views.invoice, name="invoice"),
|
||||
path(
|
||||
"transaction/<transaction_pk>/invoice/<pk>/delete",
|
||||
views.InvoiceDeleteView.as_view(),
|
||||
name="del_invoice",
|
||||
),
|
||||
path("category", views.category, name="category"),
|
||||
path("category/<uuid>", views.category, name="category"),
|
||||
path("category/<uuid>/del", views.del_category, name="del_category"),
|
||||
|
|
|
@ -61,29 +61,55 @@ class TransactionCreateView(LoginRequiredMixin, CreateView):
|
|||
form_class = TransactionForm
|
||||
|
||||
|
||||
class InvoiceCreateView(LoginRequiredMixin, CreateView):
|
||||
model = Invoice
|
||||
form_class = InvoiceForm
|
||||
|
||||
def form_valid(self, form):
|
||||
form.instance.transaction = get_object_or_404(
|
||||
Transaction, pk=self.kwargs["transaction_pk"]
|
||||
)
|
||||
return super().form_valid(form)
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse_lazy("transaction", kwargs={"pk": self.object.transaction.pk})
|
||||
|
||||
|
||||
class TransactionUpdateView(LoginRequiredMixin, UpdateView):
|
||||
model = Transaction
|
||||
form_class = TransactionForm
|
||||
|
||||
|
||||
class InvoiceUpdateView(LoginRequiredMixin, UpdateView):
|
||||
model = Invoice
|
||||
form_class = InvoiceForm
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse_lazy("transaction", kwargs={"pk": self.object.transaction.pk})
|
||||
|
||||
def get_queryset(self):
|
||||
return Invoice.objects.filter(
|
||||
transaction=get_object_or_404(Transaction, pk=self.kwargs["transaction_pk"])
|
||||
)
|
||||
|
||||
|
||||
class TransactionDeleteView(LoginRequiredMixin, DeleteView):
|
||||
model = Transaction
|
||||
template_name = "main/confirm_delete.html"
|
||||
success_url = reverse_lazy("index")
|
||||
|
||||
|
||||
@login_required
|
||||
def invoice(request, uuid):
|
||||
_invoice = get_object_or_404(Invoice, id=uuid)
|
||||
with _invoice.file.open() as _file:
|
||||
return HttpResponse(_file.read(), content_type="application/pdf")
|
||||
class InvoiceDeleteView(LoginRequiredMixin, DeleteView):
|
||||
model = Invoice
|
||||
template_name = "main/confirm_delete.html"
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse_lazy("transaction", kwargs={"pk": self.object.transaction.pk})
|
||||
|
||||
@login_required
|
||||
def del_invoice(request, uuid, invoice_id):
|
||||
_invoice = get_object_or_404(Invoice, id=invoice_id)
|
||||
_invoice.delete()
|
||||
return redirect(transaction, uuid=uuid)
|
||||
def get_queryset(self):
|
||||
return Invoice.objects.filter(
|
||||
transaction=get_object_or_404(Transaction, pk=self.kwargs["transaction_pk"])
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
|
|
Loading…
Reference in a new issue