Revised the unapplied original line item report to mark matched offsets for administrators when there are unmatched offsets.

This commit is contained in:
依瑪貓 2023-04-08 18:52:41 +08:00
parent 1660e66766
commit 79689ac0e5
4 changed files with 29 additions and 4 deletions

View File

@ -32,8 +32,9 @@ from accounting.report.utils.report_chooser import ReportChooser
from accounting.report.utils.report_type import ReportType from accounting.report.utils.report_type import ReportType
from accounting.report.utils.unapplied import get_accounts_with_unapplied from accounting.report.utils.unapplied import get_accounts_with_unapplied
from accounting.report.utils.urls import unapplied_url from accounting.report.utils.urls import unapplied_url
from accounting.unmatched_offset.forms import OffsetMatcher
from accounting.utils.pagination import Pagination from accounting.utils.pagination import Pagination
from accounting.utils.unapplied import get_unapplied_original_line_items from accounting.utils.permission import can_admin
class CSVRow(BaseCSVRow): class CSVRow(BaseCSVRow):
@ -75,11 +76,13 @@ class PageParams(BasePageParams):
"""The HTML page parameters.""" """The HTML page parameters."""
def __init__(self, account: Account, def __init__(self, account: Account,
is_mark_matches: bool,
pagination: Pagination[JournalEntryLineItem], pagination: Pagination[JournalEntryLineItem],
line_items: list[JournalEntryLineItem]): line_items: list[JournalEntryLineItem]):
"""Constructs the HTML page parameters. """Constructs the HTML page parameters.
:param account: The account. :param account: The account.
:param is_mark_matches: Whether to mark the matched offsets.
:param pagination: The pagination. :param pagination: The pagination.
:param line_items: The line items. :param line_items: The line items.
""" """
@ -89,6 +92,8 @@ class PageParams(BasePageParams):
"""The pagination.""" """The pagination."""
self.line_items: list[JournalEntryLineItem] = line_items self.line_items: list[JournalEntryLineItem] = line_items
"""The line items.""" """The line items."""
self.is_mark_matches: bool = is_mark_matches
"""Whether to mark the matched offsets."""
@property @property
def has_data(self) -> bool: def has_data(self) -> bool:
@ -148,9 +153,13 @@ class UnappliedOriginalLineItems(BaseReport):
""" """
self.__account: Account = account self.__account: Account = account
"""The account.""" """The account."""
offset_matcher: OffsetMatcher = OffsetMatcher(self.__account)
self.__line_items: list[JournalEntryLineItem] \ self.__line_items: list[JournalEntryLineItem] \
= get_unapplied_original_line_items(self.__account) = offset_matcher.unapplied
"""The line items.""" """The line items."""
self.__is_mark_matches: bool \
= can_admin() and len(offset_matcher.unmatched_offsets) > 0
"""Whether to mark the matched offsets."""
def csv(self) -> Response: def csv(self) -> Response:
"""Returns the report as CSV for download. """Returns the report as CSV for download.
@ -169,6 +178,7 @@ class UnappliedOriginalLineItems(BaseReport):
= Pagination[JournalEntryLineItem](self.__line_items, = Pagination[JournalEntryLineItem](self.__line_items,
is_reversed=True) is_reversed=True)
params: PageParams = PageParams(account=self.__account, params: PageParams = PageParams(account=self.__account,
is_mark_matches=self.__is_mark_matches,
pagination=pagination, pagination=pagination,
line_items=pagination.list) line_items=pagination.list)
return render_template("accounting/report/unapplied.html", return render_template("accounting/report/unapplied.html",

View File

@ -218,6 +218,15 @@ a.accounting-report-table-row {
.accounting-report-table-body .accounting-report-table-row:hover { .accounting-report-table-body .accounting-report-table-row:hover {
background-color: #e5e6e7; background-color: #e5e6e7;
} }
.accounting-report-table-body .accounting-report-table-row-danger {
background-color: #f8d7da;
}
.accounting-report-table-body .accounting-report-table-row-danger:nth-child(2n+1) {
background-color: #eccccf;
}
.accounting-report-table-body .accounting-report-table-row-danger:hover {
background-color: #e5c7ca;
}
.accounting-journal-table .accounting-report-table-row { .accounting-journal-table .accounting-report-table-row {
grid-template-columns: 1fr 1fr 2fr 4fr 1fr 1fr; grid-template-columns: 1fr 1fr 2fr 4fr 1fr 1fr;
} }

View File

@ -56,10 +56,15 @@ First written: 2023/4/7
</div> </div>
<div class="accounting-report-table-body"> <div class="accounting-report-table-body">
{% for line_item in report.line_items %} {% for line_item in report.line_items %}
<a class="accounting-report-table-row" href="{{ url_for("accounting.journal-entry.detail", journal_entry=line_item.journal_entry)|accounting_append_next }}"> <a class="accounting-report-table-row {% if report.is_mark_matches and not line_item.match %} accounting-report-table-row-danger {% endif %}" href="{{ url_for("accounting.journal-entry.detail", journal_entry=line_item.journal_entry)|accounting_append_next }}">
<div>{{ line_item.journal_entry.date|accounting_format_date }}</div> <div>{{ line_item.journal_entry.date|accounting_format_date }}</div>
<div>{{ line_item.currency.name }}</div> <div>{{ line_item.currency.name }}</div>
<div>{{ line_item.description|accounting_default }}</div> <div>
{{ line_item.description|accounting_default }}
{% if report.is_mark_matches and line_item.match %}
<div>{{ A_("Can match %(offset)s", offset=line_item.match) }}</div>
{% endif %}
</div>
<div class="accounting-amount">{{ line_item.amount|accounting_format_amount }}</div> <div class="accounting-amount">{{ line_item.amount|accounting_format_amount }}</div>
<div class="accounting-amount">{{ line_item.net_balance|accounting_format_amount }}</div> <div class="accounting-amount">{{ line_item.net_balance|accounting_format_amount }}</div>
</a> </a>

View File

@ -90,6 +90,7 @@ class OffsetMatcher:
continue continue
self.matched_pairs.append( self.matched_pairs.append(
OffsetPair(original_item, offset_candidates[0])) OffsetPair(original_item, offset_candidates[0]))
original_item.match = offset_candidates[0]
offset_candidates[0].match = original_item offset_candidates[0].match = original_item
remains.remove(offset_candidates[0]) remains.remove(offset_candidates[0])
self.is_having_matches = len(self.matched_pairs) > 0 self.is_having_matches = len(self.matched_pairs) > 0