Added the search page in the accounting application.
This commit is contained in:
parent
f114f84c85
commit
c6a62d92d5
174
accounting/templates/accounting/search.html
Normal file
174
accounting/templates/accounting/search.html
Normal file
@ -0,0 +1,174 @@
|
||||
{% extends "base.html" %}
|
||||
{% comment %}
|
||||
The Mia Accounting Application
|
||||
cash.html: The template for the cash account reports
|
||||
|
||||
Copyright (c) 2020 imacat.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Author: imacat@mail.imacat.idv.tw (imacat)
|
||||
First written: 2020/7/21
|
||||
{% endcomment %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
{% load humanize %}
|
||||
{% load mia_core %}
|
||||
{% load accounting %}
|
||||
|
||||
{% block settings %}
|
||||
{% blocktrans asvar title with query=request.GET.q context "Accounting|" %}Search Result for “{{ query }}”{% endblocktrans %}
|
||||
{% setvar "title" title %}
|
||||
{% setvar "use_period_chooser" True %}
|
||||
{% static "accounting/css/report.css" as css %}
|
||||
{% setvar "css" css %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="btn-group btn-actions">
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown">
|
||||
<i class="fas fa-edit"></i>
|
||||
{% trans "New" context "Accounting|" as text %}
|
||||
{{ text|force_escape }}
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
{% url "accounting:transaction.create" "expense" as url %}
|
||||
<a class="dropdown-item" href="{% url_query url r=request.get_full_path %}">
|
||||
{% trans "Cash Expense" context "Accounting|" as text %}
|
||||
{{ text|force_escape }}
|
||||
</a>
|
||||
{% url "accounting:transaction.create" "income" as url %}
|
||||
<a class="dropdown-item" href="{% url_query url r=request.get_full_path %}">
|
||||
{% trans "Cash Income" context "Accounting|" as text %}
|
||||
{{ text|force_escape }}
|
||||
</a>
|
||||
{% url "accounting:transaction.create" "transfer" as url %}
|
||||
<a class="dropdown-item" href="{% url_query url r=request.get_full_path %}">
|
||||
{% trans "Transfer" context "Accounting|" as text %}
|
||||
{{ text|force_escape }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% with current_report_icon="fas fa-search" %}
|
||||
{% trans "Search" context "Accounting|" as current_report_title %}
|
||||
{% include "accounting/include/report-chooser.html" %}
|
||||
{% endwith %}
|
||||
<form class="btn btn-primary input-group" action="{% url "accounting:search" %}" method="get">
|
||||
<input id="search-input" class="form-control form-control-sm search-input" type="text" name="q" value="{{ request.GET.q }}" />
|
||||
<label for="search-input" class="search-label">
|
||||
<button type="submit">
|
||||
<i class="fas fa-search"></i>
|
||||
{% trans "Search" context "Accounting|" as text %}
|
||||
{{ text|force_escape }}
|
||||
</button>
|
||||
</label>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{% if item_list %}
|
||||
{% include "mia_core/include/pagination.html" %}
|
||||
|
||||
{# The table for large screens #}
|
||||
<table class="table table-striped table-hover d-none d-md-table general-journal-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">{% trans "Date" context "Accounting|" as text %}{{ text|force_escape }}</th>
|
||||
<th scope="col">{% trans "Subject" context "Accounting|" as text %}{{ text|force_escape }}</th>
|
||||
<th scope="col">{% trans "Summary" context "Accounting|" as text %}{{ text|force_escape }}</th>
|
||||
<th class="amount" scope="col">{% trans "Debit" context "Accounting|" as text %}{{ text|force_escape }}</th>
|
||||
<th class="amount" scope="col">{% trans "Credit" context "Accounting|" as text %}{{ text|force_escape }}</th>
|
||||
<th scope="col">{% trans "Notes" context "Accounting|" as text %}{{ text|force_escape }}</th>
|
||||
<th class="actions" scope="col">{% trans "View" context "Accounting|" as text %}{{ text|force_escape }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for item in item_list %}
|
||||
<tr class="{% if not item.is_balanced or item.has_order_hole %} table-danger {% endif %}">
|
||||
<td>{{ item.transaction.date|smart_date }}</td>
|
||||
<td>{{ item.subject.title|title }}</td>
|
||||
<td><div class="{% if item.is_credit %} journal-credit {% else %} journal-debit {% endif %}">{{ item.summary|default:"" }}{% if not item.is_balanced %}
|
||||
<span class="badge badge-danger badge-pill">
|
||||
{% trans "Unbalanced" context "Accounting|" as text %}
|
||||
{{ text|force_escape }}
|
||||
</span>
|
||||
{% endif %}{% if item.has_order_hole %}
|
||||
<span class="badge badge-danger badge-pill">
|
||||
{% trans "Need Reorder" context "Accounting|" as text %}
|
||||
{{ text|force_escape }}
|
||||
</span>
|
||||
{% endif %}</div></td>
|
||||
<td class="amount">{{ item.debit_amount|accounting_amount }}</td>
|
||||
<td class="amount">{{ item.credit_amount|accounting_amount }}</td>
|
||||
<td>{{ item.transaction.note|default:"" }}</td>
|
||||
<td class="actions">
|
||||
<a href="{{ item.transaction.get_absolute_url }}" class="btn btn-info" role="button">
|
||||
<i class="fas fa-eye"></i>
|
||||
{% trans "View" context "Accounting|" as text %}{{ text|force_escape }}
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{# The list for small screens #}
|
||||
<ul class="list-group d-md-none">
|
||||
{% for item in item_list %}
|
||||
<li class="list-group-item {% if not item.is_balanced or item.has_order_hole %} list-group-item-danger {% endif %}">
|
||||
<a class="list-group-item-action" href="{{ item.transaction.get_absolute_url }}">
|
||||
<div class="{% if item.is_credit %} journal-credit {% else %} journal-debit {% endif %}">
|
||||
<div class="date-subject-line">
|
||||
{{ item.transaction.date|smart_date }} {{ item.subject.title|title }}
|
||||
</div>
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
{{ item.summary|default:"" }}
|
||||
{% if not item.is_balanced %}
|
||||
<span class="badge badge-danger badge-pill">
|
||||
{% trans "Unbalanced" context "Accounting|" as text %}
|
||||
{{ text|force_escape }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if item.has_order_hole %}
|
||||
<span class="badge badge-danger badge-pill">
|
||||
{% trans "Need Reorder" context "Accounting|" as text %}
|
||||
{{ text|force_escape }}
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div>
|
||||
{% if item.debit_amount is not None %}
|
||||
<span class="badge badge-success badge-pill">
|
||||
{{ item.debit_amount|intcomma:False }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if item.credit_amount is not None %}
|
||||
<span class="badge badge-warning badge-pill">
|
||||
{{ item.credit_amount|intcomma:False }}
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div>{{ item.transaction.note|default:"" }}</div>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<p>{{ _("There is currently no data.")|force_escape }}</p>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
@ -74,7 +74,7 @@ urlpatterns = [
|
||||
path("balance-sheet/<str:period_spec>",
|
||||
reports.balance_sheet, name="balance-sheet"),
|
||||
path("search",
|
||||
mia_core_views.todo, name="search"),
|
||||
reports.search, name="search"),
|
||||
path("transactions/<txn-type:type>/create",
|
||||
mia_core_views.todo, name="transactions.create"),
|
||||
path("transactions/<txn-type:type>/store",
|
||||
|
@ -26,7 +26,7 @@ from django.http import HttpResponseRedirect, Http404
|
||||
from django.shortcuts import render
|
||||
from django.urls import reverse
|
||||
from django.utils import dateformat, timezone
|
||||
from django.utils.translation import pgettext
|
||||
from django.utils.translation import pgettext, get_language
|
||||
from django.views.decorators.http import require_GET
|
||||
|
||||
from accounting.models import Record, Transaction, Subject, \
|
||||
@ -35,7 +35,7 @@ from accounting.utils import ReportUrl
|
||||
from mia import settings
|
||||
from mia_core.digest_auth import digest_login_required
|
||||
from mia_core.period import Period
|
||||
from mia_core.utils import Pagination
|
||||
from mia_core.utils import Pagination, get_multi_lingual_search
|
||||
|
||||
|
||||
@require_GET
|
||||
@ -791,6 +791,34 @@ def balance_sheet(request, period_spec):
|
||||
})
|
||||
|
||||
|
||||
@require_GET
|
||||
@digest_login_required
|
||||
def search(request):
|
||||
"""The search.
|
||||
|
||||
Args:
|
||||
request (HttpRequest) The request.
|
||||
|
||||
Returns:
|
||||
HttpResponse: The response.
|
||||
"""
|
||||
# The accounting records
|
||||
query = request.GET.get("q")
|
||||
if query is None:
|
||||
records = []
|
||||
else:
|
||||
records = Record.objects.filter(
|
||||
get_multi_lingual_search("subject__title", query)
|
||||
| Q(subject__code__icontains=query)
|
||||
| Q(summary__icontains=query)
|
||||
| Q(transaction__note__icontains=query))
|
||||
pagination = Pagination(request, records, True)
|
||||
return render(request, "accounting/search.html", {
|
||||
"item_list": pagination.items,
|
||||
"pagination": pagination,
|
||||
})
|
||||
|
||||
|
||||
def _get_period(period_spec):
|
||||
"""Obtains the period helper.
|
||||
|
||||
|
@ -22,7 +22,7 @@ import random
|
||||
import urllib.parse
|
||||
|
||||
from django.conf import settings
|
||||
from django.db.models import Model
|
||||
from django.db.models import Model, Q
|
||||
from django.utils.translation import pgettext, get_language
|
||||
|
||||
|
||||
@ -104,6 +104,27 @@ def get_multi_lingual_attr(model, name, default=None):
|
||||
return getattr(model, name + Language.default().db)
|
||||
|
||||
|
||||
def get_multi_lingual_search(attr, query):
|
||||
"""Returns the query condition on a multi-lingual attribute.
|
||||
|
||||
Args:
|
||||
attr (str): The base name of the multi-lingual attribute.
|
||||
query (str): The query.
|
||||
|
||||
Returns:
|
||||
Q: The query condition
|
||||
"""
|
||||
language = Language.current()
|
||||
if language.is_default:
|
||||
return Q(**{attr + language.db + "__icontains": query})
|
||||
default = Language.default()
|
||||
q = (Q(**{attr + language.db + "__isnull": False})
|
||||
& Q(**{attr + language.db + "__icontains": query}))\
|
||||
| (Q(**{attr + language.db + "__isnull": True})
|
||||
& Q(**{attr + default.db + "__icontains": query}))
|
||||
return q
|
||||
|
||||
|
||||
class UrlBuilder:
|
||||
"""The URL builder.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user