Implement basic quotation functionality
This commit is contained in:
parent
122a702fd1
commit
5b4860a3bf
11 changed files with 288 additions and 7 deletions
|
@ -31,8 +31,8 @@ navigations["backend_main"].add_section(clients_section)
|
||||||
|
|
||||||
quotes_section = NavSection("Quotes")
|
quotes_section = NavSection("Quotes")
|
||||||
|
|
||||||
quote_list_item = NavItem("List Quotes", "fa-file-invoice-dollar", "backendni")
|
quote_list_item = NavItem("List Quotes", "fa-file-invoice-dollar", "quotes")
|
||||||
quote_create_item = NavItem("Create Quote", "fa-plus-square", "backendni")
|
quote_create_item = NavItem("Create Quote", "fa-plus-square", "quotes_create")
|
||||||
|
|
||||||
quotes_section.add_item(quote_list_item)
|
quotes_section.add_item(quote_list_item)
|
||||||
quotes_section.add_item(quote_create_item)
|
quotes_section.add_item(quote_create_item)
|
||||||
|
|
|
@ -9,8 +9,9 @@ from core.urls.backend.firewall import urlpatterns as firewallpatterns
|
||||||
from core.urls.backend.invoices import urlpatterns as invoicepatterns
|
from core.urls.backend.invoices import urlpatterns as invoicepatterns
|
||||||
from core.urls.backend.clientgroups import urlpatterns as clientgrouppatterns
|
from core.urls.backend.clientgroups import urlpatterns as clientgrouppatterns
|
||||||
from core.urls.backend.currencies import urlpatterns as currencypatterns
|
from core.urls.backend.currencies import urlpatterns as currencypatterns
|
||||||
|
from core.urls.backend.quotes import urlpatterns as quotepatterns
|
||||||
|
|
||||||
urlpatterns = adminpatterns + clientpatterns + dbsettingspatterns + brandpatterns + firewallpatterns + invoicepatterns + clientgrouppatterns + currencypatterns
|
urlpatterns = adminpatterns + clientpatterns + dbsettingspatterns + brandpatterns + firewallpatterns + invoicepatterns + clientgrouppatterns + currencypatterns + quotepatterns
|
||||||
|
|
||||||
urlpatterns.append(path('admin/', DashboardView.as_view(), name="dashboard"))
|
urlpatterns.append(path('admin/', DashboardView.as_view(), name="dashboard"))
|
||||||
urlpatterns.append(path('admin/oops/', BackendNotImplementedView.as_view(), name="backendni"))
|
urlpatterns.append(path('admin/oops/', BackendNotImplementedView.as_view(), name="backendni"))
|
10
core/urls/backend/quotes.py
Normal file
10
core/urls/backend/quotes.py
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
from django.urls import path
|
||||||
|
|
||||||
|
from core.views.backend.quotes import QuoteCreateView, QuoteDeleteView, QuoteEditView, QuoteListView
|
||||||
|
|
||||||
|
urlpatterns = []
|
||||||
|
|
||||||
|
urlpatterns.append(path('admin/quotes/', QuoteListView.as_view(), name="quotes"))
|
||||||
|
urlpatterns.append(path("admin/quotes/<pk>/delete/", QuoteDeleteView.as_view(), name="quotes_delete"))
|
||||||
|
urlpatterns.append(path("admin/quotes/<pk>/edit/", QuoteEditView.as_view(), name="quotes_edit"))
|
||||||
|
urlpatterns.append(path("admin/quotes/create/", QuoteCreateView.as_view(), name="quotes_create"))
|
|
@ -13,7 +13,7 @@ class InvoiceEditView(BackendUpdateView):
|
||||||
template_name = f"{settings.EXPEPHALON_BACKEND}/invoices/update.html"
|
template_name = f"{settings.EXPEPHALON_BACKEND}/invoices/update.html"
|
||||||
model = Invoice
|
model = Invoice
|
||||||
success_url = reverse_lazy("invoices")
|
success_url = reverse_lazy("invoices")
|
||||||
fields = ["name", "logo", "address1", "address2", "zip", "city", "state", "country", "vat_id", "company_id"]
|
fields = ["client", "brand", "number", "created", "due", "payment_method", "currency"]
|
||||||
title = "Edit Invoice"
|
title = "Edit Invoice"
|
||||||
|
|
||||||
class InvoiceDeleteView(BackendDeleteView):
|
class InvoiceDeleteView(BackendDeleteView):
|
||||||
|
|
30
core/views/backend/quotes.py
Normal file
30
core/views/backend/quotes.py
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
from django.conf import settings
|
||||||
|
from django.urls import reverse_lazy
|
||||||
|
|
||||||
|
from core.models.quotes import QuoteItem, Quote
|
||||||
|
from core.views.backend.generic import BackendListView, BackendUpdateView, BackendDeleteView, BackendCreateView
|
||||||
|
|
||||||
|
class QuoteListView(BackendListView):
|
||||||
|
template_name = f"{settings.EXPEPHALON_BACKEND}/quotes/index.html"
|
||||||
|
model = Quote
|
||||||
|
title = "Quotes"
|
||||||
|
|
||||||
|
class QuoteEditView(BackendUpdateView):
|
||||||
|
template_name = f"{settings.EXPEPHALON_BACKEND}/quotes/update.html"
|
||||||
|
model = Quote
|
||||||
|
success_url = reverse_lazy("quotes")
|
||||||
|
fields = ["client", "brand", "number", "created", "expiry", "currency"]
|
||||||
|
title = "Edit Quote"
|
||||||
|
|
||||||
|
class QuoteDeleteView(BackendDeleteView):
|
||||||
|
template_name = f"{settings.EXPEPHALON_BACKEND}/quotes/delete.html"
|
||||||
|
model = Quote
|
||||||
|
success_url = reverse_lazy("quotes")
|
||||||
|
title = "Delete Quote"
|
||||||
|
|
||||||
|
class QuoteCreateView(BackendCreateView):
|
||||||
|
template_name = f"{settings.EXPEPHALON_BACKEND}/quotes/create.html"
|
||||||
|
model = Quote
|
||||||
|
success_url = reverse_lazy("quotes")
|
||||||
|
fields = ["client", "brand", "number", "created", "expiry", "currency"]
|
||||||
|
title = "Create Quote"
|
|
@ -40,7 +40,7 @@
|
||||||
<button type="submit" class="btn-shadow mr-3 btn btn-success">
|
<button type="submit" class="btn-shadow mr-3 btn btn-success">
|
||||||
<i class="fa fa-check"></i> Save
|
<i class="fa fa-check"></i> Save
|
||||||
</button>
|
</button>
|
||||||
<a href="{% url "admins" %}" class="btn-shadow mr-3 btn btn-danger">
|
<a href="{% url "invoices" %}" class="btn-shadow mr-3 btn btn-danger">
|
||||||
<i class="fa fa-times"></i> Cancel
|
<i class="fa fa-times"></i> Cancel
|
||||||
</a>
|
</a>
|
||||||
{% endbuttons %}
|
{% endbuttons %}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<i class="fa fa-users-cog">
|
<i class="fa fa-users-cog">
|
||||||
</i>
|
</i>
|
||||||
</div>
|
</div>
|
||||||
<div>Invoice - Edit Invoice
|
<div>Invoices - Edit Invoice
|
||||||
<div class="page-title-subheading">Edit invoice
|
<div class="page-title-subheading">Edit invoice
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
<button type="submit" class="btn-shadow mr-3 btn btn-success">
|
<button type="submit" class="btn-shadow mr-3 btn btn-success">
|
||||||
<i class="fa fa-check"></i> Save
|
<i class="fa fa-check"></i> Save
|
||||||
</button>
|
</button>
|
||||||
<a href="{% url "admins" %}" class="btn-shadow mr-3 btn btn-danger">
|
<a href="{% url "quotes" %}" class="btn-shadow mr-3 btn btn-danger">
|
||||||
<i class="fa fa-times"></i> Cancel
|
<i class="fa fa-times"></i> Cancel
|
||||||
</a>
|
</a>
|
||||||
{% endbuttons %}
|
{% endbuttons %}
|
||||||
|
|
57
templates/backend/quotes/create.html
Normal file
57
templates/backend/quotes/create.html
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
{% extends "backend/base.html" %}
|
||||||
|
{% load bootstrap4 %}
|
||||||
|
{% block content %}
|
||||||
|
<div class="app-page-title">
|
||||||
|
<div class="page-title-wrapper">
|
||||||
|
<div class="page-title-heading">
|
||||||
|
<div class="page-title-icon">
|
||||||
|
<i class="fa fa-users-cog">
|
||||||
|
</i>
|
||||||
|
</div>
|
||||||
|
<div>Quotes - Create Quote
|
||||||
|
<div class="page-title-subheading">Create a new quote
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="page-title-actions">
|
||||||
|
<button type="button" data-toggle="tooltip" title="New Quote" data-placement="bottom" class="btn-shadow mr-3 btn btn-success">
|
||||||
|
<i class="fa fa-plus"></i> New Quote
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12 col-lg-0">
|
||||||
|
<div class="mb-3 card">
|
||||||
|
<div class="card-header-tab card-header-tab-animation card-header">
|
||||||
|
<div class="card-header-title">
|
||||||
|
<i class="header-icon lnr-apartment icon-gradient bg-love-kiss"> </i>
|
||||||
|
Create Quote
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="tab-content">
|
||||||
|
<div class="tab-pane fade show active" id="tabs-eg-77">
|
||||||
|
<form method="POST" enctype="multipart/form-data" >
|
||||||
|
{% csrf_token %}
|
||||||
|
{% bootstrap_form form %}
|
||||||
|
{% buttons %}
|
||||||
|
<button type="submit" class="btn-shadow mr-3 btn btn-success">
|
||||||
|
<i class="fa fa-check"></i> Save
|
||||||
|
</button>
|
||||||
|
<a href="{% url "quotes" %}" class="btn-shadow mr-3 btn btn-danger">
|
||||||
|
<i class="fa fa-times"></i> Cancel
|
||||||
|
</a>
|
||||||
|
{% endbuttons %}
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
57
templates/backend/quotes/delete.html
Normal file
57
templates/backend/quotes/delete.html
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
{% extends "backend/base.html" %}
|
||||||
|
{% load bootstrap4 %}
|
||||||
|
{% block content %}
|
||||||
|
<div class="app-page-title">
|
||||||
|
<div class="page-title-wrapper">
|
||||||
|
<div class="page-title-heading">
|
||||||
|
<div class="page-title-icon">
|
||||||
|
<i class="fa fa-database">
|
||||||
|
</i>
|
||||||
|
</div>
|
||||||
|
<div>Quotes - Delete Quote
|
||||||
|
<div class="page-title-subheading">Delete an quote from the system
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="page-title-actions">
|
||||||
|
<button type="button" data-toggle="tooltip" title="New Rule" data-placement="bottom" class="btn-shadow mr-3 btn btn-success">
|
||||||
|
<i class="fa fa-plus"></i> New Quote
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12 col-lg-0">
|
||||||
|
<div class="mb-3 card">
|
||||||
|
<div class="card-header-tab card-header-tab-animation card-header">
|
||||||
|
<div class="card-header-title">
|
||||||
|
<i class="header-icon lnr-apartment icon-gradient bg-love-kiss"> </i>
|
||||||
|
Deleting invoice {{ object.number or object.id }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="tab-content">
|
||||||
|
<div class="tab-pane fade show active" id="tabs-eg-77">
|
||||||
|
<form method="POST">
|
||||||
|
{% csrf_token %}
|
||||||
|
Are you sure you wish to delete quote {{ object.number or object.id }}?
|
||||||
|
{% buttons %}
|
||||||
|
<button type="submit" class="btn-shadow mr-3 btn btn-success">
|
||||||
|
<i class="fa fa-check"></i> Save
|
||||||
|
</button>
|
||||||
|
<a href="{% url "quotes" %}" class="btn-shadow mr-3 btn btn-danger">
|
||||||
|
<i class="fa fa-times"></i> Cancel
|
||||||
|
</a>
|
||||||
|
{% endbuttons %}
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
69
templates/backend/quotes/index.html
Normal file
69
templates/backend/quotes/index.html
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
{% extends "backend/base.html" %}
|
||||||
|
{% block content %}
|
||||||
|
<div class="app-page-title">
|
||||||
|
<div class="page-title-wrapper">
|
||||||
|
<div class="page-title-heading">
|
||||||
|
<div class="page-title-icon">
|
||||||
|
<i class="fa fa-shield-alt">
|
||||||
|
</i>
|
||||||
|
</div>
|
||||||
|
<div>Quotes
|
||||||
|
<div class="page-title-subheading">Create, edit and delete quotes
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="page-title-actions">
|
||||||
|
<a href="{% url "quotes_create" %}" type="button" data-toggle="tooltip" title="New Invoice" data-placement="bottom" class="btn-shadow mr-3 btn btn-success">
|
||||||
|
<i class="fa fa-plus"></i> New Quote
|
||||||
|
</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12 col-lg-0">
|
||||||
|
<div class="mb-3 card">
|
||||||
|
<div class="card-header-tab card-header-tab-animation card-header">
|
||||||
|
<div class="card-header-title">
|
||||||
|
<i class="header-icon lnr-apartment icon-gradient bg-love-kiss"> </i>
|
||||||
|
Active Quotes
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="tab-content">
|
||||||
|
<div class="tab-pane fade show active" id="tabs-eg-77">
|
||||||
|
<div class="card mb-3 widget-chart widget-chart2 text-left w-100">
|
||||||
|
<table class="mb-0 table table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>Quote Number</th>
|
||||||
|
<th>Recipient</th>
|
||||||
|
<th>Total (net)</th>
|
||||||
|
<th>Total (gross)</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>Options</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for quote in object_list %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ quote.id }}</td>
|
||||||
|
<td>{{ quote.number }}</td>
|
||||||
|
<td>{{ quote.client.user.get_full_name }}</td>
|
||||||
|
<td>{{ quote.total_net }}</td>
|
||||||
|
<td>{{ quote.total_gross }}</td>
|
||||||
|
<td>{{ quote.status }}</td>
|
||||||
|
<td><a href="{% url "quotes_edit" quote.id %}"><i class="fas fa-edit" title="Edit Quote"></i></a> <a href="{% url "quotes_delete" quote.id %}"><i style="color: darkred;" class="fas fa-trash-alt" title="Delete Quote"></i></a></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
57
templates/backend/quotes/update.html
Normal file
57
templates/backend/quotes/update.html
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
{% extends "backend/base.html" %}
|
||||||
|
{% load bootstrap4 %}
|
||||||
|
{% block content %}
|
||||||
|
<div class="app-page-title">
|
||||||
|
<div class="page-title-wrapper">
|
||||||
|
<div class="page-title-heading">
|
||||||
|
<div class="page-title-icon">
|
||||||
|
<i class="fa fa-users-cog">
|
||||||
|
</i>
|
||||||
|
</div>
|
||||||
|
<div>Quotes - Edit Quote
|
||||||
|
<div class="page-title-subheading">Edit quote
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="page-title-actions">
|
||||||
|
<button type="button" data-toggle="tooltip" title="New Quote" data-placement="bottom" class="btn-shadow mr-3 btn btn-success">
|
||||||
|
<i class="fa fa-plus"></i> New Quote
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12 col-lg-0">
|
||||||
|
<div class="mb-3 card">
|
||||||
|
<div class="card-header-tab card-header-tab-animation card-header">
|
||||||
|
<div class="card-header-title">
|
||||||
|
<i class="header-icon lnr-apartment icon-gradient bg-love-kiss"> </i>
|
||||||
|
Editing {{ object.number or object.id }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="tab-content">
|
||||||
|
<div class="tab-pane fade show active" id="tabs-eg-77">
|
||||||
|
<form method="POST" enctype="multipart/form-data" >
|
||||||
|
{% csrf_token %}
|
||||||
|
{% bootstrap_form form %}
|
||||||
|
{% buttons %}
|
||||||
|
<button type="submit" class="btn-shadow mr-3 btn btn-success">
|
||||||
|
<i class="fa fa-check"></i> Save
|
||||||
|
</button>
|
||||||
|
<a href="{% url "quotes" %}" class="btn-shadow mr-3 btn btn-danger">
|
||||||
|
<i class="fa fa-times"></i> Cancel
|
||||||
|
</a>
|
||||||
|
{% endbuttons %}
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
Loading…
Reference in a new issue