Added the view of the account details in the accounting applications.

This commit is contained in:
依瑪貓 2020-08-08 15:18:39 +08:00
parent fd397a6692
commit 734cd2320b
4 changed files with 200 additions and 4 deletions

View File

@ -63,7 +63,7 @@ class Account(DirtyFieldsMixin, models.Model):
self.amount = None
self.is_for_debit = None
self.is_for_credit = None
self.is_in_use = None
self._is_in_use = None
self._is_parent_and_in_use = None
def __str__(self):
@ -105,6 +105,22 @@ class Account(DirtyFieldsMixin, models.Model):
def is_parent_and_in_use(self, value):
self._is_parent_and_in_use = value
@property
def is_in_use(self):
"""Whether this account is in use.
Returns:
bool: True if this account is in use, or false otherwise.
"""
if self._is_in_use is None:
self._is_in_use = self.child_set.count() > 0\
or self.record_set.count() > 0
return self._is_in_use
@is_in_use.setter
def is_in_use(self, value):
self._is_in_use = value
class Transaction(DirtyFieldsMixin, models.Model):
"""An accounting transaction."""

View File

@ -0,0 +1,173 @@
{% extends "base.html" %}
{% comment %}
The Mia Accounting Application
account_detail.html: The template for the account detail
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/8/8
{% endcomment %}
{% load static %}
{% load i18n %}
{% load mia_core %}
{% load accounting %}
{% block settings %}
{% setvar "title" account %}
{% endblock %}
{% block content %}
{% if account.is_parent_and_in_use %}
<div class="alert alert-danger alert-dismissible fade show">
<button type="button" class="close" data-dismiss="alert">&times;</button>
<strong>{{ _("Error:")|force_escape }}</strong> {{ _("The account is a parent account but is also used in the accounting records.")|force_escape }}
</div>
{% endif %}
<!-- the delete confirmation dialog -->
<form action="{% url_keep_return "accounting:accounts.delete" account %}" method="post">
{% csrf_token %}
<!-- The Modal -->
<div class="modal" id="del-modal">
<div class="modal-dialog">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<h4 class="modal-title">{{ _("Account Deletion Confirmation")|force_escape }}</h4>
<button type="button" class="close" data-dismiss="modal">&times;</button>
</div>
<!-- Modal body -->
<div class="modal-body">{{ _("Do you really want to delete this account?")|force_escape }}</div>
<!-- Modal footer -->
<div class="modal-footer">
<button class="btn btn-danger" type="submit" name="del-confirm">{{ _("Confirm")|force_escape }}</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">{{ _("Cancel")|force_escape }}</button>
</div>
</div>
</div>
</div>
</form>
<div class="btn-group btn-actions">
<a class="btn btn-primary" role="button" href="{% if "r" in request.GET %}{{ request.GET.r }}{% else %}{% url "accounting:accounts" %}{% endif %}">
<i class="fas fa-chevron-circle-left"></i>
{{ _("Back")|force_escape }}
</a>
<a class="btn btn-primary" role="button" href="{% url "accounting:accounts.edit" account %}">
<i class="fas fa-user-cog"></i>
{{ _("Setting")|force_escape }}
</a>
{% if not account.is_in_use %}
<button type="button" class="btn btn-secondary d-none d-sm-inline" disabled="disabled" title="{{ _("This account is not used in the accounting records.")|force_escape }}">
<i class="fas fa-file-invoice-dollar"></i>
{{ _("Ledger")|force_escape }}
</button>
{% else %}
<a class="btn btn-primary d-none d-sm-inline" role="button" href="{% url "accounting:ledger" account "-" %}">
<i class="fas fa-file-invoice-dollar"></i>
{{ _("Ledger")|force_escape }}
</a>
{% endif %}
<div class="btn-group d-sm-none">
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">
<i class="fas fa-bars"></i>
</button>
<div class="dropdown-menu">
{% if not account.is_in_use %}
<span class="dropdown-item disabled" title="{{ _("This account is not used in the accounting records.")|force_escape }}">
<i class="fas fa-file-invoice-dollar"></i>
{{ _("Ledger")|force_escape }}
</span>
{% else %}
<a class="dropdown-item" href="{% url "accounting:ledger" account "-" %}">
<i class="fas fa-file-invoice-dollar"></i>
{{ _("Ledger")|force_escape }}
</a>
{% endif %}
</div>
</div>
{% if account.is_in_use %}
<button class="btn btn-secondary" type="button" disabled="disabled" title="{{ _("This account is in use.")|force_escape }}">
<i class="fas fa-trash"></i>
{{ _("Delete")|force_escape }}
</button>
{% else %}
<button class="btn btn-danger" type="button" data-toggle="modal" data-target="#del-modal">
<i class="fas fa-trash"></i>
{{ _("Delete")|force_escape }}
</button>
{% endif %}
</div>
<div class="row form-group">
<div class="col-sm-2">{{ _("Parent Account:")|force_escape }}</div>
<div class="col-sm-10">
{% if account.parent %}
{{ account.parent }}
{% else %}
{{ _("Topmost")|force_escape }}
{% endif %}
</div>
</div>
<div class="row form-group">
<div class="col-sm-2">{{ _("Code:")|force_escape }}</div>
<div class="col-sm-10">{{ account.code }}</div>
</div>
<div class="row form-group">
<div class="col-sm-2">{{ _("Title:")|force_escape }}</div>
<div class="col-sm-10">{{ account.title }}</div>
</div>
<div class="row form-group">
<div class="col-sm-2">{{ _("Child Accounts:")|force_escape }}</div>
<div class="col-sm-10">
{% for child in account.child_set.all %}
<a class="btn btn-primary" type="role" href="{% url_with_return "accounting:accounts.show" child %}">
{{ child }}
</a>
{% empty %}
{{ _("This subject is an end-point subject.")|force_escape }}
{% endfor %}
</div>
</div>
<div class="row form-group">
<div class="col-sm-2">{{ _("Created at:")|force_escape }}</div>
<div class="col-sm-10">{{ account.created_at }}</div>
</div>
<div class="row form-group">
<div class="col-sm-2">{{ _("Created by:")|force_escape }}</div>
<div class="col-sm-10">{{ account.created_by }}</div>
</div>
<div class="row form-group">
<div class="col-sm-2">{{ _("Updated at:")|force_escape }}</div>
<div class="col-sm-10">{{ account.updated_at }}</div>
</div>
<div class="row form-group">
<div class="col-sm-2">{{ _("Updated by:")|force_escape }}</div>
<div class="col-sm-10">{{ account.updated_by }}</div>
</div>
{% endblock %}

View File

@ -101,9 +101,8 @@ urlpatterns = [
mia_core_views.todo, name="accounts.store"),
path("accounts/options",
views.account_options, name="accounts.options"),
# TODO: To be done
path("accounts/<account:account>",
mia_core_views.todo, name="accounts.show"),
views.AccountView.as_view(), name="accounts.show"),
# TODO: To be done
path("accounts/<account:account>/edit",
mia_core_views.todo, name="accounts.edit"),

View File

@ -34,7 +34,7 @@ from django.utils import timezone
from django.utils.decorators import method_decorator
from django.utils.translation import gettext as _, gettext_noop
from django.views.decorators.http import require_GET, require_POST
from django.views.generic import RedirectView, ListView
from django.views.generic import RedirectView, ListView, DetailView
from mia_core.digest_auth import login_required
from mia_core.period import Period
@ -1045,6 +1045,14 @@ class AccountListView(ListView):
context_object_name = "account_list"
@method_decorator(require_GET, name="dispatch")
@method_decorator(login_required, name="dispatch")
class AccountView(DetailView):
"""The view of an account."""
def get_object(self, queryset=None):
return self.request.resolver_match.kwargs["account"]
@require_GET
@login_required
def account_options(request):