Removed the list_transactions view that is not used now.
This commit is contained in:
parent
531e90e8ad
commit
f59378002e
@ -1,96 +0,0 @@
|
|||||||
{#
|
|
||||||
The Mia! Accounting Flask Project
|
|
||||||
list.html: The transaction list
|
|
||||||
|
|
||||||
Copyright (c) 2023 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: 2023/2/18
|
|
||||||
#}
|
|
||||||
{% extends "accounting/base.html" %}
|
|
||||||
|
|
||||||
{% block accounting_scripts %}
|
|
||||||
<script src="{{ url_for("accounting.static", filename="js/material-fab-speed-dial.js") }}"></script>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block header %}{% block title %}{% if request.args.q %}{{ A_("Search Result for \"%(query)s\"", query=request.args.q) }}{% else %}{{ A_("Transaction Management") }}{% endif %}{% endblock %}{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
|
|
||||||
<div class="btn-group mb-2 d-none d-md-inline-flex">
|
|
||||||
{% if accounting_can_edit() %}
|
|
||||||
<div class="btn-group" role="group">
|
|
||||||
<button type="button" class="btn btn-primary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
|
|
||||||
<i class="fa-solid fa-plus"></i>
|
|
||||||
{{ A_("New") }}
|
|
||||||
</button>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" href="{{ url_for("accounting.transaction.create", txn_type=txn_types.CASH_EXPENSE)|accounting_append_next }}">
|
|
||||||
{{ A_("Cash Expense") }}</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" href="{{ url_for("accounting.transaction.create", txn_type=txn_types.CASH_INCOME)|accounting_append_next }}">
|
|
||||||
{{ A_("Cash Income") }}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" href="{{ url_for("accounting.transaction.create", txn_type=txn_types.TRANSFER)|accounting_append_next }}">
|
|
||||||
{{ A_("Transfer") }}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<form class="btn btn-primary d-flex input-group accounting-search-desktop-form" action="{{ url_for("accounting.report.search") }}" method="get" role="search" aria-label="{{ A_("Search for Desktop") }}">
|
|
||||||
<input id="accounting-search-desktop" class="form-control form-control-sm accounting-search-input" type="search" name="q" value="{{ request.args.q }}" placeholder=" " required="required">
|
|
||||||
<label for="accounting-search-desktop" class="accounting-search-label">
|
|
||||||
<button type="submit">
|
|
||||||
<i class="fa-solid fa-magnifying-glass"></i>
|
|
||||||
{{ A_("Search") }}
|
|
||||||
</button>
|
|
||||||
</label>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="btn-group mb-2 d-md-none">
|
|
||||||
<form class="btn btn-primary d-flex input-group" action="{{ url_for("accounting.report.search") }}" method="get" role="search" aria-label="{{ A_("Search for Mobile") }}">
|
|
||||||
<input id="accounting-search-mobile" class="form-control form-control-sm accounting-search-input" type="search" name="q" value="{{ request.args.q }}" placeholder=" " required="required">
|
|
||||||
<label for="accounting-search-mobile" class="accounting-search-label">
|
|
||||||
<button type="submit">
|
|
||||||
<i class="fa-solid fa-magnifying-glass"></i>
|
|
||||||
{{ A_("Search") }}
|
|
||||||
</button>
|
|
||||||
</label>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% include "accounting/include/add-txn-material-fab.html" %}
|
|
||||||
|
|
||||||
{% if list %}
|
|
||||||
{% include "accounting/include/pagination.html" %}
|
|
||||||
|
|
||||||
<div class="list-group">
|
|
||||||
{% for item in list %}
|
|
||||||
<a class="list-group-item list-group-item-action" href="{{ url_for("accounting.transaction.detail", txn=item)|accounting_append_next }}">
|
|
||||||
{{ item.date|accounting_format_date }} {{ item }}
|
|
||||||
</a>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<p>{{ A_("There is no data.") }}</p>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% endblock %}
|
|
@ -1,65 +0,0 @@
|
|||||||
# The Mia! Accounting Flask Project.
|
|
||||||
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/2/18
|
|
||||||
|
|
||||||
# Copyright (c) 2023 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.
|
|
||||||
"""The queries for the transaction management.
|
|
||||||
|
|
||||||
"""
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
import sqlalchemy as sa
|
|
||||||
from flask import request
|
|
||||||
|
|
||||||
from accounting.models import Transaction
|
|
||||||
from accounting.utils.query import parse_query_keywords
|
|
||||||
|
|
||||||
|
|
||||||
def get_transaction_query() -> list[Transaction]:
|
|
||||||
"""Returns the transactions, optionally filtered by the query.
|
|
||||||
|
|
||||||
:return: The transactions.
|
|
||||||
"""
|
|
||||||
keywords: list[str] = parse_query_keywords(request.args.get("q"))
|
|
||||||
if len(keywords) == 0:
|
|
||||||
return Transaction.query\
|
|
||||||
.order_by(Transaction.date, Transaction.no).all()
|
|
||||||
conditions: list[sa.BinaryExpression] = []
|
|
||||||
for k in keywords:
|
|
||||||
sub_conditions: list[sa.BinaryExpression] \
|
|
||||||
= [Transaction.note.contains(k)]
|
|
||||||
date: datetime
|
|
||||||
try:
|
|
||||||
date = datetime.strptime(k, "%Y")
|
|
||||||
sub_conditions.append(
|
|
||||||
sa.extract("year", Transaction.date) == date.year)
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
try:
|
|
||||||
date = datetime.strptime(k, "%Y/%m")
|
|
||||||
sub_conditions.append(sa.and_(
|
|
||||||
sa.extract("year", Transaction.date) == date.year,
|
|
||||||
sa.extract("month", Transaction.date) == date.month))
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
try:
|
|
||||||
date = datetime.strptime(f"2000/{k}", "%Y/%m/%d")
|
|
||||||
sub_conditions.append(sa.and_(
|
|
||||||
sa.extract("month", Transaction.date) == date.month,
|
|
||||||
sa.extract("day", Transaction.date) == date.day))
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
conditions.append(sa.or_(*sub_conditions))
|
|
||||||
return Transaction.query.filter(*conditions)\
|
|
||||||
.order_by(Transaction.date, Transaction.no).all()
|
|
@ -30,13 +30,11 @@ from accounting.locale import lazy_gettext
|
|||||||
from accounting.models import Transaction
|
from accounting.models import Transaction
|
||||||
from accounting.utils.flash_errors import flash_form_errors
|
from accounting.utils.flash_errors import flash_form_errors
|
||||||
from accounting.utils.next_uri import inherit_next, or_next
|
from accounting.utils.next_uri import inherit_next, or_next
|
||||||
from accounting.utils.pagination import Pagination
|
|
||||||
from accounting.utils.permission import has_permission, can_view, can_edit
|
from accounting.utils.permission import has_permission, can_view, can_edit
|
||||||
from accounting.utils.txn_types import TransactionType
|
from accounting.utils.txn_types import TransactionType
|
||||||
from accounting.utils.user import get_current_user_pk
|
from accounting.utils.user import get_current_user_pk
|
||||||
from .forms import sort_transactions_in, TransactionReorderForm
|
from .forms import sort_transactions_in, TransactionReorderForm
|
||||||
from .operators import TransactionOperator, TXN_TYPE_TO_OP, get_txn_op
|
from .operators import TransactionOperator, TXN_TYPE_TO_OP, get_txn_op
|
||||||
from .queries import get_transaction_query
|
|
||||||
from .template_filters import with_type, to_transfer, format_amount_input, \
|
from .template_filters import with_type, to_transfer, format_amount_input, \
|
||||||
text2html
|
text2html
|
||||||
|
|
||||||
@ -49,20 +47,6 @@ bp.add_app_template_filter(format_amount_input,
|
|||||||
bp.add_app_template_filter(text2html, "accounting_txn_text2html")
|
bp.add_app_template_filter(text2html, "accounting_txn_text2html")
|
||||||
|
|
||||||
|
|
||||||
@bp.get("", endpoint="list")
|
|
||||||
@has_permission(can_view)
|
|
||||||
def list_transactions() -> str:
|
|
||||||
"""Lists the transactions.
|
|
||||||
|
|
||||||
:return: The transaction list.
|
|
||||||
"""
|
|
||||||
transactions: list[Transaction] = get_transaction_query()
|
|
||||||
pagination: Pagination = Pagination[Transaction](transactions)
|
|
||||||
return render_template("accounting/transaction/list.html",
|
|
||||||
list=pagination.list, pagination=pagination,
|
|
||||||
txn_types=TransactionType)
|
|
||||||
|
|
||||||
|
|
||||||
@bp.get("/create/<transactionType:txn_type>", endpoint="create")
|
@bp.get("/create/<transactionType:txn_type>", endpoint="create")
|
||||||
@has_permission(can_edit)
|
@has_permission(can_edit)
|
||||||
def show_add_transaction_form(txn_type: TransactionType) -> str:
|
def show_add_transaction_form(txn_type: TransactionType) -> str:
|
||||||
|
@ -84,9 +84,6 @@ class CashIncomeTransactionTestCase(unittest.TestCase):
|
|||||||
update_form["csrf_token"] = csrf_token
|
update_form["csrf_token"] = csrf_token
|
||||||
response: httpx.Response
|
response: httpx.Response
|
||||||
|
|
||||||
response = client.get(PREFIX)
|
|
||||||
self.assertEqual(response.status_code, 403)
|
|
||||||
|
|
||||||
response = client.get(f"{PREFIX}/{txn_id}")
|
response = client.get(f"{PREFIX}/{txn_id}")
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 403)
|
||||||
|
|
||||||
@ -119,9 +116,6 @@ class CashIncomeTransactionTestCase(unittest.TestCase):
|
|||||||
update_form["csrf_token"] = csrf_token
|
update_form["csrf_token"] = csrf_token
|
||||||
response: httpx.Response
|
response: httpx.Response
|
||||||
|
|
||||||
response = client.get(PREFIX)
|
|
||||||
self.assertEqual(response.status_code, 200)
|
|
||||||
|
|
||||||
response = client.get(f"{PREFIX}/{txn_id}")
|
response = client.get(f"{PREFIX}/{txn_id}")
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
@ -151,9 +145,6 @@ class CashIncomeTransactionTestCase(unittest.TestCase):
|
|||||||
update_form: dict[str, str] = self.__get_update_form(txn_id)
|
update_form: dict[str, str] = self.__get_update_form(txn_id)
|
||||||
response: httpx.Response
|
response: httpx.Response
|
||||||
|
|
||||||
response = self.client.get(PREFIX)
|
|
||||||
self.assertEqual(response.status_code, 200)
|
|
||||||
|
|
||||||
response = self.client.get(f"{PREFIX}/{txn_id}")
|
response = self.client.get(f"{PREFIX}/{txn_id}")
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
@ -645,9 +636,6 @@ class CashExpenseTransactionTestCase(unittest.TestCase):
|
|||||||
update_form["csrf_token"] = csrf_token
|
update_form["csrf_token"] = csrf_token
|
||||||
response: httpx.Response
|
response: httpx.Response
|
||||||
|
|
||||||
response = client.get(PREFIX)
|
|
||||||
self.assertEqual(response.status_code, 403)
|
|
||||||
|
|
||||||
response = client.get(f"{PREFIX}/{txn_id}")
|
response = client.get(f"{PREFIX}/{txn_id}")
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 403)
|
||||||
|
|
||||||
@ -680,9 +668,6 @@ class CashExpenseTransactionTestCase(unittest.TestCase):
|
|||||||
update_form["csrf_token"] = csrf_token
|
update_form["csrf_token"] = csrf_token
|
||||||
response: httpx.Response
|
response: httpx.Response
|
||||||
|
|
||||||
response = client.get(PREFIX)
|
|
||||||
self.assertEqual(response.status_code, 200)
|
|
||||||
|
|
||||||
response = client.get(f"{PREFIX}/{txn_id}")
|
response = client.get(f"{PREFIX}/{txn_id}")
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
@ -712,9 +697,6 @@ class CashExpenseTransactionTestCase(unittest.TestCase):
|
|||||||
update_form: dict[str, str] = self.__get_update_form(txn_id)
|
update_form: dict[str, str] = self.__get_update_form(txn_id)
|
||||||
response: httpx.Response
|
response: httpx.Response
|
||||||
|
|
||||||
response = self.client.get(PREFIX)
|
|
||||||
self.assertEqual(response.status_code, 200)
|
|
||||||
|
|
||||||
response = self.client.get(f"{PREFIX}/{txn_id}")
|
response = self.client.get(f"{PREFIX}/{txn_id}")
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
@ -1213,9 +1195,6 @@ class TransferTransactionTestCase(unittest.TestCase):
|
|||||||
update_form["csrf_token"] = csrf_token
|
update_form["csrf_token"] = csrf_token
|
||||||
response: httpx.Response
|
response: httpx.Response
|
||||||
|
|
||||||
response = client.get(PREFIX)
|
|
||||||
self.assertEqual(response.status_code, 403)
|
|
||||||
|
|
||||||
response = client.get(f"{PREFIX}/{txn_id}")
|
response = client.get(f"{PREFIX}/{txn_id}")
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 403)
|
||||||
|
|
||||||
@ -1248,9 +1227,6 @@ class TransferTransactionTestCase(unittest.TestCase):
|
|||||||
update_form["csrf_token"] = csrf_token
|
update_form["csrf_token"] = csrf_token
|
||||||
response: httpx.Response
|
response: httpx.Response
|
||||||
|
|
||||||
response = client.get(PREFIX)
|
|
||||||
self.assertEqual(response.status_code, 200)
|
|
||||||
|
|
||||||
response = client.get(f"{PREFIX}/{txn_id}")
|
response = client.get(f"{PREFIX}/{txn_id}")
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
@ -1280,9 +1256,6 @@ class TransferTransactionTestCase(unittest.TestCase):
|
|||||||
update_form: dict[str, str] = self.__get_update_form(txn_id)
|
update_form: dict[str, str] = self.__get_update_form(txn_id)
|
||||||
response: httpx.Response
|
response: httpx.Response
|
||||||
|
|
||||||
response = self.client.get(PREFIX)
|
|
||||||
self.assertEqual(response.status_code, 200)
|
|
||||||
|
|
||||||
response = self.client.get(f"{PREFIX}/{txn_id}")
|
response = self.client.get(f"{PREFIX}/{txn_id}")
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user