Added the pagination navigation bar and the action buttons to the cash account in the accounting application.

This commit is contained in:
依瑪貓 2020-07-11 07:12:53 +08:00
parent 241445bc7a
commit d7f04dbb39
8 changed files with 471 additions and 23 deletions

View File

@ -24,30 +24,70 @@ First written: 2020/7/1
{% load humanize %}
{% block settings %}
{% trans "Cash Account for {} in {}" context "Accounting|" as title %}
{% str_format title subject.title_zhtw period.description as title %}
{% blocktrans asvar title with subject=subject.title_zhtw period=period.description context "Accounting|" %}Cash Account for {{ subject }} in {{ period }}{% endblocktrans %}
{% setvar "title" title %}
{% setvar "use_period_chooser" True %}
{% endblock %}
{% block content %}
<p>{{ request.resolver_match.url_name }}</p>
<p>{{ request.resolver_match.app_name }}</p>
<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-money-bill-wave" %}
{% trans "Cash Account" context "Accounting|" as current_report_title %}
{% include "accounting/include/report-chooser.html" %}
{% endwith %}
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#period-modal">
<i class="far fa-calendar-alt"></i>
<span class="d-none d-md-inline">{{ period.description }}</span>
<span class="d-md-none">{% trans "Period" context "Period|" as text %}{{ text|force_escape }}</span>
</button>
</div>
{% include "mia_core/include/period-chooser.html" %}
{% if records %}
{% include "mia_core/pagination.html" %}
{% 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|" %}</th>
<th scope="col">{% trans "Subject" context "Accounting|" %}</th>
<th scope="col">{% trans "Summary" context "Accounting|" %}</th>
<th class="amount" scope="col">{% trans "Income" context "Accounting|" %}</th>
<th class="amount" scope="col">{% trans "Expense" context "Accounting|" %}</th>
<th class="amount" scope="col">{% trans "Balance" context "Accounting|" %}</th>
<th class="actions" scope="col">{% trans "View" context "Accounting|" %}</th>
<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 "Income" context "Accounting|" as text %}{{ text|force_escape }}</th>
<th class="amount" scope="col">{% trans "Expense" context "Accounting|" as text %}{{ text|force_escape }}</th>
<th class="amount" scope="col">{% trans "Balance" 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>
@ -57,11 +97,13 @@ First written: 2020/7/1
<td>{{ record.subject.title_zhtw }}</td>
<td>{{ record.summary }}{% if not record.transaction.is_balanced %}
<span class="badge badge-danger badge-pill">
{% trans "Unbalanced" context "Accounting|" %}
{% trans "Unbalanced" context "Accounting|" as text %}
{{ text|force_escape }}
</span>
{% endif %}{% if record.transaction.has_order_hole %}
<span class="badge badge-danger badge-pill">
{% trans "Need Reorder" context "Accounting|" %}
{% trans "Need Reorder" context "Accounting|" as text %}
{{ text|force_escape }}
</span>
{% endif %}</td>
<td class="amount">{{ record.credit_amount|default:""|intcomma:False }}</td>
@ -70,7 +112,7 @@ First written: 2020/7/1
<td class="actions">
<a href="{{ record.transaction.get_absolute_url }}" class="btn btn-info" role="button">
<i class="fas fa-eye"></i>
<span class="d-none d-lg-inline">{% trans "View" context "Accounting|" %}</span>
<span class="d-none d-lg-inline">{% trans "View" context "Accounting|" as text %}{{ text|force_escape }}</span>
</a>
</td>
</tr>
@ -91,12 +133,14 @@ First written: 2020/7/1
{{ record.summary }}
{% if not record.transaction.is_balanced %}
<span class="badge badge-danger badge-pill">
{% trans "Unbalanced" context "Accounting|" %}
{% trans "Unbalanced" context "Accounting|" as text %}
{{ text|force_escape }}
</span>
{% endif %}
{% if record.transaction.has_order_hole %}
<span class="badge badge-danger badge-pill">
{% trans "Need Reorder" context "Accounting|" %}
{% trans "Need Reorder" context "Accounting|" as text %}
{{ text|force_escape }}
</span>
{% endif %}
</div>
@ -110,7 +154,7 @@ First written: 2020/7/1
{% endfor %}
</ul>
{% else %}
<p>{% trans "There is currently no data." %}</p>
<p>{{ _("There is currently no data.")|force_escape }}</p>
{% endif %}
{% endblock %}

View File

@ -0,0 +1,117 @@
{% comment %}
The Mia Accounting Application
cash.html: The template for the accounting cash 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/9
{% endcomment %}
{% load i18n %}
<!-- the accounting record search dialog -->
<form action="{% url "accounting:search" %}" method="GET">
<!-- The Modal -->
<div class="modal" id="accounting-search-modal">
<div class="modal-dialog">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<h4 class="modal-title">{% trans "Search Accounting Records" context "Accounting|" as text %}{{ text|force_escape }}</h4>
<button type="button" class="close" data-dismiss="modal">&times;</button>
</div>
<!-- Modal body -->
<div class="modal-body">
<label for="accounting-query">{% trans "Search:" context "Accounting|" as text %}{{ text|force_escape }}</label>
{% trans "e.g. Coffee" context "Accounting|" as text %}
<input id="accounting-query" type="text" name="q" value="{% if request.resolver_match.url_name == "search" %}{{ request.GET.q }}{% endif %}" placeholder="{{ text|force_escape }}" required="required" />
</div>
<!-- Modal footer -->
<div class="modal-footer">
<button class="btn btn-primary" type="submit">
<i class="fas fa-search"></i>
{% trans "Search" context "Accounting|" as text %}{{ text|force_escape }}
</button>
</div>
</div>
</div>
</div>
</form>
<!-- the report chooser button -->
<div class="btn-group">
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown">
<span class="d-none d-md-inline">
<i class="{{ current_report_icon }}"></i>
{{ current_report_title }}
</span>
<span class="d-md-none">{% trans "Book" context "Accounting|" as text %}{{ text|force_escape }}</span>
</button>
<div class="dropdown-menu subject-picker">
<a class="dropdown-item {% if request.resolver_match.url_name == "cash" %} active {% endif %}" href="{% url "accounting:cash.home" %}">
<i class="fas fa-money-bill-wave"></i>
{% trans "Cash Account" context "Accounting|" as text %}
{{ text|force_escape }}
</a>
<a class="dropdown-item {% if request.resolver_match.url_name == "cash-summary" %} active {% endif %}" href="{% url "accounting:cash-summary.home" %}">
<i class="fas fa-money-bill-wave"></i>
{% trans "Cash Summary" context "Accounting|" as text %}
{{ text|force_escape }}
</a>
<a class="dropdown-item {% if request.resolver_match.url_name == "ledger" %} active {% endif %}" href="{% url "accounting:ledger.home" %}">
<i class="fas fa-file-invoice-dollar"></i>
{% trans "Ledger" context "Accounting|" as text %}
{{ text|force_escape }}
</a>
<a class="dropdown-item {% if request.resolver_match.url_name == "ledger-summary" %} active {% endif %}" href="{% url "accounting:ledger-summary.home" %}">
<i class="fas fa-file-invoice-dollar"></i>
{% trans "Ledger Summary" context "Accounting|" as text %}
{{ text|force_escape }}
</a>
<a class="dropdown-item {% if request.resolver_match.url_name == "journal" %} active {% endif %}" href="{% url "accounting:journal.home" %}">
<i class="fas fa-book"></i>
{% trans "Journal" context "Accounting|" as text %}
{{ text|force_escape }}
</a>
<a class="dropdown-item {% if request.resolver_match.url_name == "trial-balance" %} active {% endif %}" href="{% url "accounting:trial-balance.home" %}">
<i class="fas fa-balance-scale-right"></i>
{% trans "Trial Balance" context "Accounting|" as text %}
{{ text|force_escape }}
</a>
<a class="dropdown-item {% if request.resolver_match.url_name == "income-statement" %} active {% endif %}" href="{% url "accounting:income-statement.home" %}">
<i class="fas fa-file-invoice"></i>
{% trans "Income Statement" context "Accounting|" as text %}
{{ text|force_escape }}
</a>
<a class="dropdown-item {% if request.resolver_match.url_name == "balance-sheet" %} active {% endif %}" href="{% url "accounting:balance-sheet.home" %}">
<i class="fas fa-balance-scale"></i>
{% trans "Balance Sheet" context "Accounting|" as text %}
{{ text|force_escape }}
</a>
<span class="dropdown-item dropdown-search {% if request.resolver_match.url_name == "search" %} active {% endif %}" data-toggle="modal" data-target="#accounting-search-modal">
<i class="fas fa-search"></i>
{% trans "Search" context "Accounting|" as text %}
{{ text|force_escape }}
</span>
<a class="dropdown-item {% if request.resolver_match.url_name == "subjects" %} active {% endif %}" href="{% url "accounting:subjects" %}">
<i class="fas fa-list-ol"></i>
{% trans "Subjects" context "Accounting|" as text %}
{{ text|force_escape }}
</a>
</div>
</div>

View File

@ -44,22 +44,32 @@ urlpatterns = [
path("cash", views.cash_home, name="cash.home"),
path("cash/<str:subject_code>/<str:period_spec>",
views.CashReportView.as_view(), name="cash"),
path("cash-summary",
mia_core_views.todo, name="cash-summary.home"),
path("cash-summary/<str:subject_code>",
mia_core_views.todo, name="cash-summary"),
path("ledger",
mia_core_views.todo, name="ledger.home"),
path("ledger/<str:subject_code>/<str:period_spec>",
mia_core_views.todo, name="ledger"),
path("ledger-summary",
mia_core_views.todo, name="ledger-summary.home"),
path("ledger-summary/<str:subject_code>",
mia_core_views.todo, name="ledger-summary"),
path("ledger/<str:subject_code>/<str:period_spec>",
mia_core_views.todo, name="ledger"),
path("ledger-summary/<str:subject_code>",
mia_core_views.todo, name="ledger-summary"),
path("journal",
mia_core_views.todo, name="journal.home"),
path("journal/<str:period_spec>",
mia_core_views.todo, name="journal"),
path("trial-balance",
mia_core_views.todo, name="trial-balance.home"),
path("trial-balance/<str:period_spec>",
mia_core_views.todo, name="trial-balance"),
path("income-statement",
mia_core_views.todo, name="income-statement.home"),
path("income-statement/<str:period_spec>",
mia_core_views.todo, name="income-statement"),
path("balance-sheet",
mia_core_views.todo, name="balance-sheet.home"),
path("balance-sheet/<str:period_spec>",
mia_core_views.todo, name="balance-sheet"),
path("search",

View File

@ -0,0 +1,26 @@
/* The Mia Website
* period-chooser.css: The style sheet for the period chooser
*/
/* Copyright (c) 2019-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: 2019/9/12
*/
.period-shortcuts {
margin-bottom: 0.2em;
}

View File

@ -0,0 +1,109 @@
/* The Mia Website
* period-chooser.js: The JavaScript for the period chooser
*/
/* Copyright (c) 2019-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: 2019/9/14
*/
// Initializes the period chooser JavaScript.
$(function () {
$(".period-tab")
.on("click", function () {
switchPeriodTab(this);
});
$("#button-period-day")
.on("click", function () {
window.location = $("#period-url").val()
.replace("period-spec", $("#day-picker").val());
});
$("#period-start")
.on("change", function () {
$("#period-end")[0].min = this.value;
});
$("#period-end")
.on("change", function () {
$("#period-start")[0].max = this.value;
});
$("#button-period-custom")
.on("click", function () {
window.location = $("#period-url").val().replace(
"period-spec",
$("#period-start").val() + "-" + $("#period-end").val());
});
const monthPickerParams = JSON.parse($("#period-month-picker-params").val());
const monthPicker = $("#month-picker");
monthPicker.datetimepicker({
locale: monthPickerParams.locale,
inline: true,
format: "YYYY-MM",
minDate: monthPickerParams.minDate,
maxDate: monthPickerParams.maxDate,
useCurrent: false,
defaultDate: monthPickerParams.defaultDate,
});
monthPicker.on("change.datetimepicker", function (e) {
monthPickerChanged(e.date);
});
});
/**
* Turns to the page to view the records of a month when the month is
* selected.
*
* @param {moment} newDate the date with the selected new month
* @private
*/
function monthPickerChanged(newDate) {
const year = newDate.year();
const month = newDate.month() + 1;
let periodSpec;
if (month < 10) {
periodSpec = year + "-0" + month;
} else {
periodSpec = year + "-" + month;
}
window.location = $("#period-url").val()
.replace("period-spec", periodSpec);
}
/**
* Switch the period chooser to tab.
*
* @param {HTMLElement} tab the navigation tab corresponding to a type
* of period
* @private
*/
function switchPeriodTab(tab) {
const tabName = tab.id.substr("period-tab-".length);
$(".period-content").each(function () {
if (this.id === "period-content-" + tabName) {
this.classList.remove("d-none");
} else {
this.classList.add("d-none");
}
});
$(".period-tab").each(function () {
if (this.id === tab.id) {
this.classList.add("active");
} else {
this.classList.remove("active");
}
});
}

View File

@ -1,6 +1,6 @@
{% comment %}
The Mia Website
base.html: The side-wide layout template
The core application of the Mia project
pagination.html: The side-wide layout template
Copyright (c) 2020 imacat.
@ -45,4 +45,4 @@ First written: 2020/7/1
</div>
</li>
</ul>
{% endif %}
{% endif %}

View File

@ -0,0 +1,131 @@
{% comment %}
The core application of the Mia project
period-chooser.html: The side-wide layout template
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/10
{% endcomment %}
{% load i18n %}
<!-- the period chooser dialog -->
<!-- The Modal -->
<input id="period-url" type="hidden" value="{% url_period "period-spec" %}" />
<input id="period-month-picker-params" type="hidden" value="{{ period.month_picker_params }}" />
<div class="modal" id="period-modal">
<div class="modal-dialog">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<h4 class="modal-title">
<i class="far fa-calendar-alt"></i>
{% trans "Choosing Your Period" context "Period|" as text %}
{{ text|force_escape }}
</h4>
<button type="button" class="close" data-dismiss="modal">&times;</button>
</div>
<!-- Modal body -->
<ul class="nav nav-tabs">
<li class="nav-item">
<span id="period-tab-month" class="period-tab nav-link active">{% trans "Month" context "Period|" as text %}{{ text|force_escape }}</span>
</li>
<li class="nav-item">
<span id="period-tab-year" class="period-tab nav-link">{% trans "Year" context "Period|" as text %}{{ text|force_escape }}</span>
</li>
<li class="nav-item">
<span id="period-tab-day" class="period-tab nav-link">{% trans "Day" context "Period|" as text %}{{ text|force_escape }}</span>
</li>
<li class="nav-item">
<span id="period-tab-custom" class="period-tab nav-link">{% trans "Custom" context "Period|" as text %}{{ text|force_escape }}</span>
</li>
</ul>
<div id="period-content-month" class="period-content modal-body">
<div class="period-shortcuts">
{% if period.this_month is not None %}
<a class="btn btn-primary" role="button" href="{% url_period period.this_month %}">{% trans "This Month" context "Period|" as text %}{{ text|force_escape }}</a>
{% endif %}
{% if period.last_month is not None %}
<a class="btn btn-primary" role="button" href="{% url_period period.last_month %}">{% trans "Last Month" context "Period|" as text %}{{ text|force_escape }}</a>
{% endif %}
{% if period.since_last_month is not None %}
<a class="btn btn-primary" role="button" href="{% url_period period.since_last_month %}">{% trans "Last Month" context "Period|" as text %}{{ text|force_escape }}</a>
{% endif %}
</div>
{% if period.has_months_to_choose %}
<div id="month-picker" class="col-sm-7"></div>
{% endif %}
</div>
<div id="period-content-year" class="period-content modal-body d-none">
<div class="period-shortcuts">
{% if period.this_year is not None %}
<a class="btn btn-primary" role="button" href="{% url_period period.this_year %}">{% trans "This Year" context "Period|" as text %}{{ text|force_escape }}</a>
{% endif %}
{% if period.last_year is not None %}
<a class="btn btn-primary" role="button" href="{% url_period period.last_year %}">{% trans "Last Year" context "Period|" as text %}{{ text|force_escape }}</a>
{% endif %}
</div>
{% if period.has_years_to_choose %}
<ul class="nav nav-pills">
{% for year in period.years_to_choose %}
<li class="nav-item">
<a class="nav-link {% if period.spec == year|stringformat:"i" %} active {% endif %}" href="{% url_period year|stringformat:"i" %}">{{ year }}</a>
</li>
{% endfor %}
</ul>
{% endif %}
</div>
<div id="period-content-day" class="period-content modal-body d-none">
<div class="period-shortcuts">
{% if period.today is not None %}
<a class="btn btn-primary" role="button" href="{% url_period period.today %}">{% trans "Today" context "Period|" as text %}{{ text|force_escape }}</a>
{% endif %}
{% if period.yesterday is not None %}
<a class="btn btn-primary" role="button" href="{% url_period period.yesterday %}">{% trans "Yesterday" context "Period|" as text %}{{ text|force_escape }}</a>
{% endif %}
</div>
{% if period.has_days_to_choose %}
<div>
<label for="day-picker">{% trans "Date:" context "Period|" as text %}{{ text|force_escape }}</label>
<input id="day-picker" type="date" value="{{ period.chosen_day }}" min="{{ period.data_start }}" max="{{ period.data_end }}" required="required" />
</div>
<div>
<button id="button-period-day" class="btn btn-primary" type="submit">{{ _("Confirm") }}</button>
</div>
{% endif %}
</div>
<div id="period-content-custom" class="period-content modal-body d-none">
<div class="period-shortcuts">
<a class="btn btn-primary" role="button" href="{% url_period "-" %}">{% trans "All" context "Period|" as text %}{{ text|force_escape }}</a>
</div>
{% if period.has_days_to_choose %}
<div>
<label for="period-start">{% trans "From:" context "Period|" as text %}{{ text|force_escape }}</label>
<input id="period-start" type="date" value="{{ period.chosen_start }}" min="{{ period.data_start }}" max="{{ period.chosen_end }}" required="required" />
</div>
<div>
<label for="period-end">{% trans "To:" context "Period|" as text %}{{ text|force_escape }}</label>
<input id="period-end" type="date" value="{{ period.chosen_end }}" min="{{ period.chosen_start }}" max="{{ period.data_end }}" required="required" />
</div>
<div>
<button id="button-period-custom" class="btn btn-primary" type="submit">{{ _("Confirm") }}</button>
</div>
{% endif %}
</div>
</div>
</div>
</div>

View File

@ -20,6 +20,7 @@
"""
from django import template
from django.urls import reverse
from mia_core.utils import UrlBuilder
@ -72,3 +73,13 @@ def url_query(url, **kwargs):
if kwargs[key] is not None:
builder.set_param(key, kwargs[key])
return str(builder)
@register.simple_tag(takes_context=True)
def url_period(context, period_spec):
request = context["request"]
viewname = "%s:%s" % (
request.resolver_match.app_name,
request.resolver_match.url_name)
subject_code = request.resolver_match.kwargs["subject_code"]
return reverse(viewname, args=[subject_code, period_spec])