Added the unapplied original line item report.
This commit is contained in:
		| @@ -33,8 +33,9 @@ from accounting.template_globals import default_currency_code | ||||
| from accounting.utils.current_account import CurrentAccount | ||||
| from .option_link import OptionLink | ||||
| from .report_type import ReportType | ||||
| from .unapplied import get_accounts_with_unapplied | ||||
| from .urls import journal_url, ledger_url, income_expenses_url, \ | ||||
|     trial_balance_url, income_statement_url, balance_sheet_url | ||||
|     trial_balance_url, income_statement_url, balance_sheet_url, unapplied_url | ||||
|  | ||||
|  | ||||
| class ReportChooser: | ||||
| @@ -74,6 +75,7 @@ class ReportChooser: | ||||
|         self.__reports.append(self.__trial_balance) | ||||
|         self.__reports.append(self.__income_statement) | ||||
|         self.__reports.append(self.__balance_sheet) | ||||
|         self.__reports.append(self.__unapplied) | ||||
|         for report in self.__reports: | ||||
|             if report.is_active: | ||||
|                 self.current_report = report.title | ||||
| @@ -151,6 +153,20 @@ class ReportChooser: | ||||
|                           self.__active_report == ReportType.BALANCE_SHEET, | ||||
|                           fa_icon="fa-solid fa-scale-balanced") | ||||
|  | ||||
|     @property | ||||
|     def __unapplied(self) -> OptionLink: | ||||
|         """Returns the unapplied original line items. | ||||
|  | ||||
|         :return: The unapplied original line items. | ||||
|         """ | ||||
|         account: Account = self.__account | ||||
|         if not account.is_need_offset: | ||||
|             account = get_accounts_with_unapplied()[0] | ||||
|         return OptionLink(gettext("Unapplied Original Line Items"), | ||||
|                           unapplied_url(account), | ||||
|                           self.__active_report == ReportType.UNAPPLIED, | ||||
|                           fa_icon="fa-solid fa-link-slash") | ||||
|  | ||||
|     def __iter__(self) -> t.Iterator[OptionLink]: | ||||
|         """Returns the iteration of the reports. | ||||
|  | ||||
|   | ||||
| @@ -34,5 +34,7 @@ class ReportType(Enum): | ||||
|     """The income statement.""" | ||||
|     BALANCE_SHEET: str = "balance-sheet" | ||||
|     """The balance sheet.""" | ||||
|     UNAPPLIED: str = "unapplied" | ||||
|     """The unapplied original line items.""" | ||||
|     SEARCH: str = "search" | ||||
|     """The search.""" | ||||
|   | ||||
							
								
								
									
										61
									
								
								src/accounting/report/utils/unapplied.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								src/accounting/report/utils/unapplied.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,61 @@ | ||||
| # The Mia! Accounting Project. | ||||
| # Author: imacat@mail.imacat.idv.tw (imacat), 2023/4/7 | ||||
|  | ||||
| #  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 unapplied original line item utilities. | ||||
|  | ||||
| """ | ||||
| import sqlalchemy as sa | ||||
|  | ||||
| from accounting.journal_entry.utils.offset_alias import offset_alias | ||||
| from accounting.models import Account, JournalEntryLineItem | ||||
| from accounting.utils.cast import be | ||||
|  | ||||
|  | ||||
| def get_accounts_with_unapplied() -> list[Account]: | ||||
|     """Returns the accounts with unapplied original line items. | ||||
|  | ||||
|     :return: The accounts with unapplied original line items. | ||||
|     """ | ||||
|     offset: sa.Alias = offset_alias() | ||||
|     net_balance: sa.Label \ | ||||
|         = (JournalEntryLineItem.amount | ||||
|            + sa.func.sum(sa.case( | ||||
|                 (be(offset.c.is_debit == JournalEntryLineItem.is_debit), | ||||
|                  offset.c.amount), | ||||
|                 else_=-offset.c.amount))).label("net_balance") | ||||
|     select_unapplied: sa.Select \ | ||||
|         = sa.select(JournalEntryLineItem.id)\ | ||||
|         .join(Account)\ | ||||
|         .join(offset, be(JournalEntryLineItem.id | ||||
|                          == offset.c.original_line_item_id), | ||||
|               isouter=True)\ | ||||
|         .filter(Account.is_need_offset, | ||||
|                 sa.or_(sa.and_(Account.base_code.startswith("2"), | ||||
|                                sa.not_(JournalEntryLineItem.is_debit)), | ||||
|                        sa.and_(Account.base_code.startswith("1"), | ||||
|                                JournalEntryLineItem.is_debit)))\ | ||||
|         .group_by(JournalEntryLineItem.id)\ | ||||
|         .having(sa.or_(sa.func.count(offset.c.id) == 0, net_balance != 0)) | ||||
|  | ||||
|     count_func: sa.Function \ | ||||
|         = sa.func.count(JournalEntryLineItem.id) | ||||
|     select: sa.Select = sa.select(Account.id)\ | ||||
|         .join(JournalEntryLineItem, isouter=True)\ | ||||
|         .filter(JournalEntryLineItem.id.in_(select_unapplied))\ | ||||
|         .group_by(Account.id)\ | ||||
|         .having(count_func > 0) | ||||
|     return Account.query.filter(Account.id.in_(select))\ | ||||
|         .order_by(Account.base_code, Account.no).all() | ||||
| @@ -116,3 +116,12 @@ def balance_sheet_url(currency: Currency, period: Period) -> str: | ||||
|                        currency=currency) | ||||
|     return url_for("accounting-report.balance-sheet", | ||||
|                    currency=currency, period=period) | ||||
|  | ||||
|  | ||||
| def unapplied_url(account: Account) -> str: | ||||
|     """Returns the URL of the unapplied original line items. | ||||
|  | ||||
|     :param account: The account. | ||||
|     :return: The URL of the unapplied original line items. | ||||
|     """ | ||||
|     return url_for("accounting-report.unapplied", account=account) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user