aa-ledger 1.0.4__py3-none-any.whl → 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {aa_ledger-1.0.4.dist-info → aa_ledger-2.0.0.dist-info}/METADATA +5 -6
- aa_ledger-2.0.0.dist-info/RECORD +267 -0
- ledger/__init__.py +2 -2
- ledger/admin.py +23 -18
- ledger/api/__init__.py +23 -7
- ledger/api/{ledger/admin.py → admin.py} +25 -31
- ledger/api/alliance.py +755 -0
- ledger/api/character.py +786 -0
- ledger/api/corporation.py +1141 -0
- ledger/api/{helpers.py → helpers/core.py} +33 -33
- ledger/api/helpers/icons.py +372 -0
- ledger/api/helpers/planetary_helper.py +354 -0
- ledger/api/planetary.py +354 -0
- ledger/api/schema.py +240 -15
- ledger/app_settings.py +11 -27
- ledger/auth_hooks.py +2 -2
- ledger/constants.py +50 -177
- ledger/decorators.py +2 -46
- ledger/forms.py +133 -39
- ledger/helpers/billboard.py +194 -144
- ledger/helpers/cache.py +105 -0
- ledger/helpers/discord.py +2 -4
- ledger/helpers/eveonline.py +160 -0
- ledger/helpers/ledger_data.py +23 -0
- ledger/helpers/ref_type.py +53 -78
- ledger/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
- ledger/locale/cs_CZ/LC_MESSAGES/django.po +349 -193
- ledger/locale/de/LC_MESSAGES/django.mo +0 -0
- ledger/locale/de/LC_MESSAGES/django.po +528 -379
- ledger/locale/django.pot +721 -546
- ledger/locale/es/LC_MESSAGES/django.mo +0 -0
- ledger/locale/es/LC_MESSAGES/django.po +349 -194
- ledger/locale/fr_FR/LC_MESSAGES/django.mo +0 -0
- ledger/locale/fr_FR/LC_MESSAGES/django.po +349 -193
- ledger/locale/it_IT/LC_MESSAGES/django.mo +0 -0
- ledger/locale/it_IT/LC_MESSAGES/django.po +349 -193
- ledger/locale/ja/LC_MESSAGES/django.mo +0 -0
- ledger/locale/ja/LC_MESSAGES/django.po +348 -193
- ledger/locale/ko_KR/LC_MESSAGES/django.mo +0 -0
- ledger/locale/ko_KR/LC_MESSAGES/django.po +349 -193
- ledger/locale/nl_NL/LC_MESSAGES/django.mo +0 -0
- ledger/locale/nl_NL/LC_MESSAGES/django.po +349 -193
- ledger/locale/pl_PL/LC_MESSAGES/django.mo +0 -0
- ledger/locale/pl_PL/LC_MESSAGES/django.po +350 -193
- ledger/locale/ru/LC_MESSAGES/django.mo +0 -0
- ledger/locale/ru/LC_MESSAGES/django.po +348 -193
- ledger/locale/sk/LC_MESSAGES/django.mo +0 -0
- ledger/locale/sk/LC_MESSAGES/django.po +348 -193
- ledger/locale/uk/LC_MESSAGES/django.mo +0 -0
- ledger/locale/uk/LC_MESSAGES/django.po +348 -193
- ledger/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
- ledger/locale/zh_Hans/LC_MESSAGES/django.po +348 -193
- ledger/managers/character_audit_manager.py +28 -20
- ledger/managers/character_journal_manager.py +185 -357
- ledger/managers/character_mining_manager.py +52 -26
- ledger/managers/character_planetary_manager.py +178 -136
- ledger/managers/corporation_audit_manager.py +36 -27
- ledger/managers/corporation_journal_manager.py +92 -56
- ledger/managers/general_manager.py +8 -7
- ledger/migrations/0018_remove_characterplanet_ledger_char_planet__58a5b6_idx_and_more.py +44 -0
- ledger/migrations/0019_rename_characteraudit_characterowner_and_more.py +48 -0
- ledger/models/__init__.py +5 -11
- ledger/models/characteraudit.py +101 -109
- ledger/models/corporationaudit.py +94 -49
- ledger/models/general.py +105 -211
- ledger/models/helpers/update_manager.py +302 -0
- ledger/models/planetary.py +60 -205
- ledger/providers.py +101 -0
- ledger/static/ledger/css/{ledger.css → aa-ledger.css} +54 -28
- ledger/static/ledger/js/aa-ledger.js +124 -0
- ledger/static/ledger/js/charts.js +25 -1
- ledger/static/ledger/js/view-alliance-ledger.js +383 -0
- ledger/static/ledger/js/view-character-ledger.js +388 -0
- ledger/static/ledger/js/view-corporation-ledger.js +402 -0
- ledger/static/ledger/js/view-planetary.js +492 -0
- ledger/static/ledger/libs/amCharts/5.14.4/js/flow.js +2 -0
- ledger/static/ledger/libs/amCharts/5.14.4/js/index.js +2 -0
- ledger/static/ledger/libs/amCharts/5.14.4/js/percent.js +2 -0
- ledger/static/ledger/libs/amCharts/5.14.4/js/themes/Animated.js +2 -0
- ledger/static/ledger/libs/amCharts/5.14.4/js/themes/Dark.js +2 -0
- ledger/static/ledger/libs/amCharts/5.14.4/js/xy.js +2 -0
- ledger/static/ledger/libs/datatables/2.3.5/css/dataTables.bootstrap5.css +610 -0
- ledger/static/ledger/libs/datatables/2.3.5/js/dataTables.bootstrap5.js +122 -0
- ledger/static/ledger/libs/datatables/2.3.5/js/dataTables.js +14127 -0
- ledger/static/ledger/libs/datatables/Extensions/ColumnControl/1.1.1/css/columnControl.bootstrap5.css +516 -0
- ledger/static/ledger/libs/datatables/Extensions/ColumnControl/1.1.1/css/columnControl.dataTables.css +529 -0
- ledger/static/ledger/libs/datatables/Extensions/ColumnControl/1.1.1/js/columnControl.bootstrap5.js +73 -0
- ledger/static/ledger/libs/datatables/Extensions/ColumnControl/1.1.1/js/dataTables.columnControl.js +3090 -0
- ledger/static/ledger/libs/datatables/Extensions/FixedHeader/4.0.4/css/fixedHeader.bootstrap5.css +20 -0
- ledger/static/ledger/libs/datatables/Extensions/FixedHeader/4.0.4/js/dataTables.fixedHeader.js +1203 -0
- ledger/static/ledger/libs/datatables/Extensions/FixedHeader/4.0.4/js/fixedHeader.bootstrap5.js +59 -0
- ledger/tasks.py +157 -141
- ledger/templates/ledger/base.html +59 -21
- ledger/templates/ledger/bundles/aa-ledger-css.html +3 -0
- ledger/templates/ledger/bundles/aa-ledger-js.html +3 -0
- ledger/templates/ledger/bundles/view-alliance-ledger-js.html +14 -0
- ledger/templates/ledger/bundles/view-character-ledger-js.html +15 -0
- ledger/templates/ledger/bundles/view-character-planetary-css.html +3 -0
- ledger/templates/ledger/bundles/view-character-planetary-js.html +4 -0
- ledger/templates/ledger/bundles/view-corporation-ledger-js.html +15 -0
- ledger/templates/ledger/partials/modal/confirm.html +0 -1
- ledger/templates/ledger/partials/modal/request-accept-delete-alliance.html +38 -0
- ledger/templates/ledger/partials/modal/request-accept-delete-character.html +38 -0
- ledger/templates/ledger/partials/modal/request-accept-delete-corporation.html +38 -0
- ledger/templates/ledger/partials/modal/request-accept-switch-notification.html +38 -0
- ledger/templates/ledger/partials/modal/request-view-alliance-details.html +26 -0
- ledger/templates/ledger/partials/modal/request-view-character-details.html +26 -0
- ledger/templates/ledger/partials/modal/request-view-corporation-details.html +26 -0
- ledger/templates/ledger/partials/modal/request-view-extractor.html +32 -0
- ledger/templates/ledger/partials/modal/request-view-factory.html +31 -0
- ledger/templates/ledger/partials/{menu → navigation}/administration.html +8 -0
- ledger/templates/ledger/partials/{menu → navigation}/navigation.html +2 -2
- ledger/templates/ledger/partials/{administration → view-alliance-administration}/alliance_corporations.html +3 -3
- ledger/templates/ledger/partials/view-alliance-administration/dashboard.html +81 -0
- ledger/templates/ledger/partials/view-alliance-ledger/alliance-billboard.html +25 -0
- ledger/templates/ledger/partials/view-alliance-ledger/alliance-ledger-details.html +21 -0
- ledger/templates/ledger/partials/view-alliance-ledger/alliance-table.html +24 -0
- ledger/templates/ledger/partials/view-alliance-ledger/information/daily.html +18 -0
- ledger/templates/ledger/partials/view-alliance-ledger/information/hourly.html +18 -0
- ledger/templates/ledger/partials/view-alliance-ledger/information/summary.html +19 -0
- ledger/templates/ledger/partials/{administration → view-character-administration}/character.html +1 -9
- ledger/templates/ledger/partials/{administration → view-character-administration}/dashboard.html +0 -34
- ledger/templates/ledger/partials/view-character-ledger/character-billboard.html +25 -0
- ledger/templates/ledger/partials/view-character-ledger/character-ledger-details.html +21 -0
- ledger/templates/ledger/partials/view-character-ledger/character-table.html +25 -0
- ledger/templates/ledger/partials/view-character-ledger/information/daily.html +18 -0
- ledger/templates/ledger/partials/view-character-ledger/information/hourly.html +18 -0
- ledger/templates/ledger/partials/view-character-ledger/information/summary.html +19 -0
- ledger/templates/ledger/partials/view-character-planetary/extractor-table.html +24 -0
- ledger/templates/ledger/partials/view-character-planetary/factory-table.html +24 -0
- ledger/templates/ledger/partials/view-character-planetary/planetary-table.html +22 -0
- ledger/templates/ledger/partials/view-character-planetary/storage-table.html +23 -0
- ledger/templates/ledger/partials/{administration → view-corporation-administration}/corporation.html +5 -13
- ledger/templates/ledger/partials/{administration → view-corporation-administration}/corporation_characters.html +1 -1
- ledger/templates/ledger/partials/view-corporation-administration/dashboard.html +81 -0
- ledger/templates/ledger/partials/view-corporation-ledger/corporation-billboard.html +25 -0
- ledger/templates/ledger/partials/view-corporation-ledger/corporation-ledger-details.html +21 -0
- ledger/templates/ledger/partials/view-corporation-ledger/corporation-table.html +26 -0
- ledger/templates/ledger/partials/view-corporation-ledger/information/daily.html +18 -0
- ledger/templates/ledger/partials/view-corporation-ledger/information/hourly.html +18 -0
- ledger/templates/ledger/partials/view-corporation-ledger/information/summary.html +19 -0
- ledger/templates/ledger/view-administration.html +62 -0
- ledger/templates/ledger/view-alliance-administration.html +49 -0
- ledger/templates/ledger/view-alliance-ledger.html +72 -0
- ledger/templates/ledger/view-alliance-overview.html +131 -0
- ledger/templates/ledger/view-character-administration.html +42 -0
- ledger/templates/ledger/view-character-ledger.html +73 -0
- ledger/templates/ledger/view-character-overview.html +135 -0
- ledger/templates/ledger/view-character-planetary-overview.html +135 -0
- ledger/templates/ledger/view-character-planetary.html +73 -0
- ledger/templates/ledger/view-corporation-administration.html +42 -0
- ledger/templates/ledger/view-corporation-ledger.html +73 -0
- ledger/templates/ledger/view-corporation-overview.html +131 -0
- ledger/templatetags/ledger.py +3 -5
- ledger/tests/__init__.py +187 -0
- ledger/tests/test_admin.py +164 -68
- ledger/tests/test_auth_hook.py +31 -13
- ledger/tests/test_decarators.py +14 -79
- ledger/tests/test_discord_installed.py +0 -1
- ledger/tests/test_helpers/test_ledger_data.py +19 -0
- ledger/tests/test_managers/test_character_audit_manager.py +111 -69
- ledger/tests/test_managers/test_character_journal_manager.py +48 -208
- ledger/tests/test_managers/test_character_mining_manager.py +37 -16
- ledger/tests/test_managers/test_corporation_division_manager.py +66 -28
- ledger/tests/test_managers/test_corporation_journal_manager.py +39 -42
- ledger/tests/test_managers/test_general_manager.py +78 -18
- ledger/tests/test_managers/test_planetary_manager.py +73 -32
- ledger/tests/test_models/test_characteraudit.py +58 -74
- ledger/tests/test_models/test_characterminingledger.py +20 -26
- ledger/tests/test_models/test_characterwalletjournal.py +10 -33
- ledger/tests/test_models/test_corporationaudit.py +41 -35
- ledger/tests/test_models/test_corporationwalletjournal.py +35 -32
- ledger/tests/test_models/test_general.py +44 -11
- ledger/tests/test_models/test_planetary.py +14 -80
- ledger/tests/test_templatetags.py +2 -7
- ledger/tests/test_views/corporation/test_add_corp.py +16 -35
- ledger/tests/test_views/corporation/test_delete_corporation.py +66 -42
- ledger/tests/test_views/test_access.py +512 -545
- ledger/tests/test_views/test_add_ally.py +57 -46
- ledger/tests/test_views/test_add_char.py +21 -33
- ledger/tests/test_views/test_delete_character.py +24 -21
- ledger/tests/testdata/README_ESI_STUB.md +430 -0
- ledger/tests/testdata/esi_stub_openapi.py +511 -0
- ledger/tests/testdata/integrations/__init__.py +0 -0
- ledger/tests/testdata/{load_eveuniverse.py → integrations/eveuniverse.py} +0 -1
- ledger/tests/testdata/integrations/planetary.py +13 -0
- ledger/tests/testdata/json/factory.json +281 -0
- ledger/tests/testdata/json/inactive.json +281 -0
- ledger/tests/testdata/json/pins.json +175 -272
- ledger/tests/testdata/json/route.json +95 -528
- ledger/tests/testdata/test_esi_stub.py +468 -0
- ledger/tests/testdata/utils.py +601 -0
- ledger/thirdparty/charlink_hook.py +60 -30
- ledger/urls.py +0 -135
- ledger/views/alliance/add_ally.py +2 -4
- ledger/views/alliance/alliance_ledger.py +64 -147
- ledger/views/character/add_char.py +8 -10
- ledger/views/character/character_ledger.py +60 -126
- ledger/views/character/planetary.py +5 -98
- ledger/views/corporation/add_corp.py +10 -12
- ledger/views/corporation/corporation_ledger.py +65 -327
- ledger/views/index.py +92 -30
- aa_ledger-1.0.4.dist-info/RECORD +0 -236
- ledger/api/api_helper/planetary_helper.py +0 -107
- ledger/api/ledger/__init__.py +0 -7
- ledger/api/ledger/planetary.py +0 -231
- ledger/helpers/alliance.py +0 -317
- ledger/helpers/character.py +0 -251
- ledger/helpers/core.py +0 -665
- ledger/helpers/corporation.py +0 -427
- ledger/helpers/data_exporter.py +0 -452
- ledger/static/ledger/js/planetary-confirm.js +0 -66
- ledger/static/ledger/js/planetary.js +0 -143
- ledger/templates/ledger/admin.html +0 -43
- ledger/templates/ledger/allyledger/admin/alliance_administration.html +0 -46
- ledger/templates/ledger/allyledger/admin/alliance_overview.html +0 -108
- ledger/templates/ledger/allyledger/alliance_ledger.html +0 -86
- ledger/templates/ledger/bundles/character-ledger-bundles.html +0 -66
- ledger/templates/ledger/bundles/corporation-ledger-bundles.html +0 -75
- ledger/templates/ledger/bundles/ledger-bundles.html +0 -23
- ledger/templates/ledger/bundles/ledger-css.html +0 -3
- ledger/templates/ledger/bundles/planetary-bundles.html +0 -50
- ledger/templates/ledger/bundles/table-css.html +0 -3
- ledger/templates/ledger/charledger/admin/character_administration.html +0 -39
- ledger/templates/ledger/charledger/admin/character_overview.html +0 -106
- ledger/templates/ledger/charledger/character_ledger.html +0 -94
- ledger/templates/ledger/charledger/planetary/admin/planetary_overview.html +0 -123
- ledger/templates/ledger/charledger/planetary/planetary_ledger.html +0 -54
- ledger/templates/ledger/corpledger/admin/corporation_administration.html +0 -39
- ledger/templates/ledger/corpledger/admin/corporation_overview.html +0 -108
- ledger/templates/ledger/corpledger/corporation_ledger.html +0 -129
- ledger/templates/ledger/data-export.html +0 -78
- ledger/templates/ledger/error.html +0 -31
- ledger/templates/ledger/partials/form/error-message.html +0 -1
- ledger/templates/ledger/partials/information/daily.html +0 -56
- ledger/templates/ledger/partials/information/day.html +0 -48
- ledger/templates/ledger/partials/information/error.html +0 -8
- ledger/templates/ledger/partials/information/hourly.html +0 -53
- ledger/templates/ledger/partials/information/summary.html +0 -88
- ledger/templates/ledger/partials/information/view_character_content.html +0 -35
- ledger/templates/ledger/partials/modal/switchalarm_confirm.html +0 -39
- ledger/templates/ledger/partials/modal/view_extractor.html +0 -48
- ledger/templates/ledger/partials/modal/view_factory.html +0 -123
- ledger/templates/ledger/partials/table/char-ledger.html +0 -85
- ledger/templates/ledger/partials/table/corp-ledger.html +0 -66
- ledger/templates/ledger/partials/table/planetary.html +0 -18
- ledger/templates/ledger/partials/thirdparty/billboard.html +0 -22
- ledger/templates/ledger/partials/view/card.html +0 -160
- ledger/templates/ledger/permission.html +0 -2
- ledger/tests/test_helpers/test_billboard.py +0 -11
- ledger/tests/test_helpers/test_data_exporter.py +0 -207
- ledger/tests/test_tasks.py +0 -282
- ledger/tests/test_view_helpers/test_core.py +0 -47
- ledger/tests/test_views/corporation/test_corporation.py +0 -267
- ledger/tests/test_views/test_planetary.py +0 -137
- ledger/tests/testdata/esi_stub.py +0 -109
- ledger/tests/testdata/esi_stub_migration.py +0 -80
- ledger/tests/testdata/generate_characteraudit.py +0 -106
- ledger/tests/testdata/generate_corporationaudit.py +0 -74
- ledger/tests/testdata/generate_events.py +0 -31
- ledger/tests/testdata/generate_miningledger.py +0 -13
- ledger/tests/testdata/generate_planets.py +0 -48
- ledger/tests/testdata/generate_walletjournal.py +0 -42
- ledger/tests/testdata/json/czarno-pins.json +0 -240
- ledger/tests/testdata/json/czarno-routes.json +0 -165
- ledger/tests/testdata/json/pins2.json +0 -538
- {aa_ledger-1.0.4.dist-info → aa_ledger-2.0.0.dist-info}/WHEEL +0 -0
- {aa_ledger-1.0.4.dist-info → aa_ledger-2.0.0.dist-info}/licenses/LICENSE +0 -0
- /ledger/{tests/test_view_helpers → api/helpers}/__init__.py +0 -0
- /ledger/templates/ledger/bundles/{ally-administration-bundles.html → view-alliance-administration-js.html} +0 -0
- /ledger/templates/ledger/bundles/{char-administration-bundles.html → view-character-administration-js.html} +0 -0
- /ledger/templates/ledger/bundles/{corp-administration-bundles.html → view-corporation-administration-js.html} +0 -0
- /ledger/templates/ledger/partials/{administration → view-alliance-administration}/alliance.html +0 -0
- /ledger/tests/testdata/{esi.json → esi_test_data.json} +0 -0
- /ledger/tests/testdata/{allianceauth.json → integrations/allianceauth.json} +0 -0
- /ledger/tests/testdata/{load_allianceauth.py → integrations/allianceauth.py} +0 -0
- /ledger/tests/testdata/{eveentity.json → integrations/eveentity.json} +0 -0
- /ledger/tests/testdata/{load_eveentity.py → integrations/eveentity.py} +0 -0
- /ledger/tests/testdata/{eveuniverse.json → integrations/eveuniverse.json} +0 -0
- /ledger/tests/testdata/{planetary.json → integrations/planetary.json} +0 -0
|
@@ -0,0 +1,1141 @@
|
|
|
1
|
+
# Standard Library
|
|
2
|
+
from collections import defaultdict
|
|
3
|
+
from decimal import Decimal
|
|
4
|
+
|
|
5
|
+
# Third Party
|
|
6
|
+
from ninja import NinjaAPI, Schema
|
|
7
|
+
|
|
8
|
+
# Django
|
|
9
|
+
from django.contrib.humanize.templatetags.humanize import intcomma
|
|
10
|
+
from django.core.handlers.wsgi import WSGIRequest
|
|
11
|
+
from django.db.models import Q, QuerySet
|
|
12
|
+
from django.utils import timezone
|
|
13
|
+
from django.utils.translation import gettext as _
|
|
14
|
+
|
|
15
|
+
# Alliance Auth
|
|
16
|
+
from allianceauth.authentication.models import UserProfile
|
|
17
|
+
from allianceauth.services.hooks import get_extension_logger
|
|
18
|
+
|
|
19
|
+
# AA Ledger
|
|
20
|
+
from ledger import __title__
|
|
21
|
+
from ledger.api.helpers.core import (
|
|
22
|
+
get_corporationowner_or_none,
|
|
23
|
+
)
|
|
24
|
+
from ledger.api.helpers.icons import (
|
|
25
|
+
get_corporation_details_info_button,
|
|
26
|
+
get_corporation_ledger_popover_button,
|
|
27
|
+
get_ref_type_details_popover_button,
|
|
28
|
+
)
|
|
29
|
+
from ledger.api.schema import (
|
|
30
|
+
BillboardSchema,
|
|
31
|
+
CategorySchema,
|
|
32
|
+
CorporationLedgerRequestInfo,
|
|
33
|
+
EntitySchema,
|
|
34
|
+
LedgerDetailsResponse,
|
|
35
|
+
LedgerDetailsSummary,
|
|
36
|
+
LedgerResponse,
|
|
37
|
+
LedgerSchema,
|
|
38
|
+
OwnerSchema,
|
|
39
|
+
)
|
|
40
|
+
from ledger.constants import NPC_ENTITIES
|
|
41
|
+
from ledger.helpers.billboard import BillboardSystem
|
|
42
|
+
from ledger.helpers.cache import CacheManager
|
|
43
|
+
from ledger.helpers.eveonline import get_character_portrait_url
|
|
44
|
+
from ledger.helpers.ledger_data import get_footer_text_class
|
|
45
|
+
from ledger.helpers.ref_type import RefTypeManager
|
|
46
|
+
from ledger.models.corporationaudit import (
|
|
47
|
+
CorporationOwner,
|
|
48
|
+
CorporationWalletJournalEntry,
|
|
49
|
+
)
|
|
50
|
+
from ledger.models.general import EveEntity
|
|
51
|
+
from ledger.providers import AppLogger
|
|
52
|
+
|
|
53
|
+
logger = AppLogger(get_extension_logger(__name__), __title__)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class LedgerEntitySchema(Schema):
|
|
57
|
+
entity: EntitySchema
|
|
58
|
+
ledger: LedgerSchema
|
|
59
|
+
actions: str = ""
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class CorporationLedgerResponse(LedgerResponse):
|
|
63
|
+
"""
|
|
64
|
+
Schema for Corporation Ledger Response.
|
|
65
|
+
|
|
66
|
+
This schema represents the response structure for corporation ledger data,
|
|
67
|
+
extending the base :class:`LedgerResponse` to include corporation-specific ledger data.
|
|
68
|
+
|
|
69
|
+
Attributes:
|
|
70
|
+
information (CorporationLedgerRequestInfo): The request information for the corporation ledger.
|
|
71
|
+
entities (list[LedgerEntitySchema]): The list of ledger entities.
|
|
72
|
+
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
information: CorporationLedgerRequestInfo
|
|
76
|
+
entities: list[LedgerEntitySchema]
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class CorporationApiEndpoints:
|
|
80
|
+
tags = ["Corporation"]
|
|
81
|
+
|
|
82
|
+
# pylint: disable=too-many-statements, function-redefined, duplicate-code
|
|
83
|
+
# flake8: noqa: F811
|
|
84
|
+
def __init__(self, api: NinjaAPI):
|
|
85
|
+
self.cache_manager = CacheManager()
|
|
86
|
+
self.billboard = BillboardSystem()
|
|
87
|
+
|
|
88
|
+
@api.get(
|
|
89
|
+
"corporation/{corporation_id}/division/{division_id}/date/{year}/",
|
|
90
|
+
response={200: CorporationLedgerResponse, 403: dict, 404: dict},
|
|
91
|
+
tags=self.tags,
|
|
92
|
+
)
|
|
93
|
+
def get_corporation_ledger(
|
|
94
|
+
request: WSGIRequest, corporation_id: int, division_id: int, year: int
|
|
95
|
+
):
|
|
96
|
+
"""Get the ledger for a character for a specific year. Admin Endpoint."""
|
|
97
|
+
return self._ledger_api_response(
|
|
98
|
+
request=request,
|
|
99
|
+
corporation_id=corporation_id,
|
|
100
|
+
division_id=division_id,
|
|
101
|
+
year=year,
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
@api.get(
|
|
105
|
+
"corporation/{corporation_id}/division/{division_id}/date/{year}/{month}/",
|
|
106
|
+
response={200: CorporationLedgerResponse, 403: dict, 404: dict},
|
|
107
|
+
tags=self.tags,
|
|
108
|
+
)
|
|
109
|
+
def get_corporation_ledger(
|
|
110
|
+
request: WSGIRequest,
|
|
111
|
+
corporation_id: int,
|
|
112
|
+
division_id: int,
|
|
113
|
+
year: int,
|
|
114
|
+
month: int,
|
|
115
|
+
):
|
|
116
|
+
"""Get the ledger for a character for a specific year. Admin Endpoint."""
|
|
117
|
+
return self._ledger_api_response(
|
|
118
|
+
request=request,
|
|
119
|
+
corporation_id=corporation_id,
|
|
120
|
+
division_id=division_id,
|
|
121
|
+
year=year,
|
|
122
|
+
month=month,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
@api.get(
|
|
126
|
+
"corporation/{corporation_id}/division/{division_id}/date/{year}/{month}/{day}/",
|
|
127
|
+
response={200: CorporationLedgerResponse, 403: dict, 404: dict},
|
|
128
|
+
tags=self.tags,
|
|
129
|
+
)
|
|
130
|
+
def get_corporation_ledger(
|
|
131
|
+
request: WSGIRequest,
|
|
132
|
+
corporation_id: int,
|
|
133
|
+
division_id: int,
|
|
134
|
+
year: int,
|
|
135
|
+
month: int,
|
|
136
|
+
day: int,
|
|
137
|
+
):
|
|
138
|
+
"""Get the ledger for a character for a specific year. Admin Endpoint."""
|
|
139
|
+
return self._ledger_api_response(
|
|
140
|
+
request=request,
|
|
141
|
+
corporation_id=corporation_id,
|
|
142
|
+
division_id=division_id,
|
|
143
|
+
year=year,
|
|
144
|
+
month=month,
|
|
145
|
+
day=day,
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
@api.get(
|
|
149
|
+
"corporation/{corporation_id}/date/{year}/",
|
|
150
|
+
response={200: CorporationLedgerResponse, 403: dict, 404: dict},
|
|
151
|
+
tags=self.tags,
|
|
152
|
+
)
|
|
153
|
+
def get_corporation_ledger(
|
|
154
|
+
request: WSGIRequest, corporation_id: int, year: int
|
|
155
|
+
):
|
|
156
|
+
"""Get the ledger for a character for a specific year. Admin Endpoint."""
|
|
157
|
+
return self._ledger_api_response(
|
|
158
|
+
request=request,
|
|
159
|
+
corporation_id=corporation_id,
|
|
160
|
+
year=year,
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
@api.get(
|
|
164
|
+
"corporation/{corporation_id}/date/{year}/{month}/",
|
|
165
|
+
response={200: CorporationLedgerResponse, 403: dict, 404: dict},
|
|
166
|
+
tags=self.tags,
|
|
167
|
+
)
|
|
168
|
+
def get_corporation_ledger(
|
|
169
|
+
request: WSGIRequest, corporation_id: int, year: int, month: int
|
|
170
|
+
):
|
|
171
|
+
"""Get the ledger for a character for a specific year. Admin Endpoint."""
|
|
172
|
+
return self._ledger_api_response(
|
|
173
|
+
request=request,
|
|
174
|
+
corporation_id=corporation_id,
|
|
175
|
+
year=year,
|
|
176
|
+
month=month,
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
@api.get(
|
|
180
|
+
"corporation/{corporation_id}/date/{year}/{month}/{day}/",
|
|
181
|
+
response={200: CorporationLedgerResponse, 403: dict, 404: dict},
|
|
182
|
+
tags=self.tags,
|
|
183
|
+
)
|
|
184
|
+
def get_corporation_ledger(
|
|
185
|
+
request: WSGIRequest,
|
|
186
|
+
corporation_id: int,
|
|
187
|
+
year: int,
|
|
188
|
+
month: int,
|
|
189
|
+
day: int,
|
|
190
|
+
):
|
|
191
|
+
"""Get the ledger for a character for a specific year. Admin Endpoint."""
|
|
192
|
+
return self._ledger_api_response(
|
|
193
|
+
request=request,
|
|
194
|
+
corporation_id=corporation_id,
|
|
195
|
+
year=year,
|
|
196
|
+
month=month,
|
|
197
|
+
day=day,
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
# pylint: disable=duplicate-code
|
|
201
|
+
def _create_datatable_footer(
|
|
202
|
+
self,
|
|
203
|
+
entities: list[LedgerEntitySchema],
|
|
204
|
+
request_info: CorporationLedgerRequestInfo,
|
|
205
|
+
) -> CorporationLedgerRequestInfo:
|
|
206
|
+
"""
|
|
207
|
+
Create the footer HTML for the Ledger datatable.
|
|
208
|
+
|
|
209
|
+
This Helper function creates the footer HTML for the Ledger datatable
|
|
210
|
+
by summing up the respective fields from the list of entities.
|
|
211
|
+
|
|
212
|
+
Args:
|
|
213
|
+
entities (list[LedgerEntitySchema]): The list of entity ledger data.
|
|
214
|
+
|
|
215
|
+
Returns:
|
|
216
|
+
str: The generated footer HTML.
|
|
217
|
+
"""
|
|
218
|
+
total_bounty = sum(entity.ledger.bounty for entity in entities)
|
|
219
|
+
total_ess = sum(entity.ledger.ess for entity in entities)
|
|
220
|
+
total_costs = sum(entity.ledger.costs for entity in entities)
|
|
221
|
+
total_miscellaneous = sum(entity.ledger.miscellaneous for entity in entities)
|
|
222
|
+
total_total = sum(entity.ledger.total for entity in entities)
|
|
223
|
+
|
|
224
|
+
# Generate Details Link
|
|
225
|
+
url = get_corporation_details_info_button(
|
|
226
|
+
entity_id=request_info.owner_id,
|
|
227
|
+
request_info=request_info,
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
# Skip Footer if no Totals
|
|
231
|
+
if total_total == 0:
|
|
232
|
+
return ""
|
|
233
|
+
|
|
234
|
+
footer_html = f"""
|
|
235
|
+
<tr>
|
|
236
|
+
<th class="border-top">{_("Summary")}</th>
|
|
237
|
+
<th class="border-top text-end {get_footer_text_class(total_bounty)}">{intcomma(value=int(total_bounty), use_l10n=True)} ISK</th>
|
|
238
|
+
<th class="border-top text-end {get_footer_text_class(total_ess)}">{intcomma(value=int(total_ess), use_l10n=True)} ISK</th>
|
|
239
|
+
<th class="border-top text-end {get_footer_text_class(total_miscellaneous)}">{intcomma(value=int(total_miscellaneous), use_l10n=True)} ISK</th>
|
|
240
|
+
<th class="border-top text-end {get_footer_text_class(total_costs)}">{intcomma(value=int(total_costs), use_l10n=True)} ISK</th>
|
|
241
|
+
<th class="border-start border-top text-end {get_footer_text_class(total_total)}">{intcomma(value=int(total_total), use_l10n=True)} ISK</th>
|
|
242
|
+
<th class="border-top">{url}</th>
|
|
243
|
+
</tr>
|
|
244
|
+
"""
|
|
245
|
+
request_info.footer_html = footer_html
|
|
246
|
+
return request_info
|
|
247
|
+
|
|
248
|
+
def _sum_by_ref_types(
|
|
249
|
+
self, entry_list: list[dict], ref_types: list[str], sign: str | None = None
|
|
250
|
+
) -> Decimal:
|
|
251
|
+
"""Helper function to sum amounts in entry_list filtered by ref_types and sign.
|
|
252
|
+
|
|
253
|
+
Args:
|
|
254
|
+
entry_list (list[dict]): List of ledger entry dicts.
|
|
255
|
+
ref_types (list[str]): Reference types to include.
|
|
256
|
+
sign (str|None): If "positive", include only positive amounts; if "negative", only negative amounts.
|
|
257
|
+
|
|
258
|
+
Returns:
|
|
259
|
+
Decimal: The summed amount.
|
|
260
|
+
"""
|
|
261
|
+
total = Decimal("0.00")
|
|
262
|
+
for r in entry_list:
|
|
263
|
+
if r.get("ref_type") in ref_types:
|
|
264
|
+
amt = r.get("amount") or Decimal("0.00")
|
|
265
|
+
if sign == "positive" and amt <= 0:
|
|
266
|
+
continue
|
|
267
|
+
if sign == "negative" and amt >= 0:
|
|
268
|
+
continue
|
|
269
|
+
total += amt
|
|
270
|
+
return total
|
|
271
|
+
|
|
272
|
+
# pylint: disable=too-many-locals
|
|
273
|
+
def _process_entity_entries(
|
|
274
|
+
self,
|
|
275
|
+
entity: EntitySchema,
|
|
276
|
+
request_info: CorporationLedgerRequestInfo,
|
|
277
|
+
entries_by_entity: dict[int, list[dict]],
|
|
278
|
+
processed_entry_ids: set[int] | None = None,
|
|
279
|
+
) -> LedgerEntitySchema | None:
|
|
280
|
+
"""
|
|
281
|
+
Process the entity entries for the corporation owner.
|
|
282
|
+
|
|
283
|
+
This Helper function processes the entity entries for the corporation
|
|
284
|
+
based on the provided date query.
|
|
285
|
+
|
|
286
|
+
Args:
|
|
287
|
+
owner (CorporationOwner): The corporation owner object.
|
|
288
|
+
request_info (LedgerRequestInfo): The request information object.
|
|
289
|
+
Returns:
|
|
290
|
+
list[EntitySchema]: A list of entity schemas for each processed entity.
|
|
291
|
+
"""
|
|
292
|
+
# Build combined entry list for primary entity and any alt_ids
|
|
293
|
+
combined_entries: list[dict] = []
|
|
294
|
+
combined_entries.extend(entries_by_entity.get(entity.entity_id, []))
|
|
295
|
+
|
|
296
|
+
# Initialize processed ids set if not provided
|
|
297
|
+
if processed_entry_ids is None:
|
|
298
|
+
processed_entry_ids = set()
|
|
299
|
+
|
|
300
|
+
# If this EntitySchema carries alt_ids (members), include those rows too
|
|
301
|
+
alt_ids = getattr(entity, "alt_ids", None) or []
|
|
302
|
+
for aid in alt_ids:
|
|
303
|
+
combined_entries.extend(entries_by_entity.get(aid, []))
|
|
304
|
+
|
|
305
|
+
# Filter out already processed entries
|
|
306
|
+
entry_list = [
|
|
307
|
+
r for r in combined_entries if r.get("entry_id") not in processed_entry_ids
|
|
308
|
+
]
|
|
309
|
+
|
|
310
|
+
# Skip Entity if no Ledger Entries
|
|
311
|
+
if not entry_list:
|
|
312
|
+
# logger.debug(f"Skipping Entity {entity} - No Ledger Entries")
|
|
313
|
+
return None
|
|
314
|
+
|
|
315
|
+
# Deduplicate by entry_id (an entry may appear under multiple alt_ids)
|
|
316
|
+
unique: dict[int, dict] = {}
|
|
317
|
+
for r in entry_list:
|
|
318
|
+
unique[r["entry_id"]] = r
|
|
319
|
+
|
|
320
|
+
# Collect Entry IDs to Mark as Processed
|
|
321
|
+
entry_ids = list(unique.keys())
|
|
322
|
+
entry_list = list(unique.values())
|
|
323
|
+
|
|
324
|
+
# Aggregate Data using in-memory rows
|
|
325
|
+
entity_bounty = self._sum_by_ref_types(entry_list, RefTypeManager.BOUNTY_PRIZES)
|
|
326
|
+
entity_ess = self._sum_by_ref_types(entry_list, RefTypeManager.ESS_TRANSFER)
|
|
327
|
+
entity_costs = self._sum_by_ref_types(
|
|
328
|
+
entry_list, RefTypeManager.ledger_ref_types(), sign="negative"
|
|
329
|
+
)
|
|
330
|
+
entity_miscellaneous = self._sum_by_ref_types(
|
|
331
|
+
entry_list, RefTypeManager.ledger_ref_types(), sign="positive"
|
|
332
|
+
)
|
|
333
|
+
|
|
334
|
+
total = sum(
|
|
335
|
+
[
|
|
336
|
+
entity_bounty,
|
|
337
|
+
entity_ess,
|
|
338
|
+
entity_miscellaneous,
|
|
339
|
+
entity_costs,
|
|
340
|
+
]
|
|
341
|
+
)
|
|
342
|
+
|
|
343
|
+
response_entity = LedgerEntitySchema(
|
|
344
|
+
entity=entity,
|
|
345
|
+
ledger=LedgerSchema(
|
|
346
|
+
bounty=entity_bounty,
|
|
347
|
+
ess=entity_ess,
|
|
348
|
+
costs=entity_costs,
|
|
349
|
+
miscellaneous=entity_miscellaneous,
|
|
350
|
+
total=total,
|
|
351
|
+
),
|
|
352
|
+
actions=get_corporation_details_info_button(
|
|
353
|
+
entity_id=entity.entity_id, request_info=request_info, section="single"
|
|
354
|
+
),
|
|
355
|
+
)
|
|
356
|
+
# Mark these entries as processed so they won't be used again
|
|
357
|
+
processed_entry_ids.update(entry_ids)
|
|
358
|
+
return response_entity
|
|
359
|
+
|
|
360
|
+
def process_member_ledger_data(
|
|
361
|
+
self,
|
|
362
|
+
entity_ids: set[int],
|
|
363
|
+
request_info: CorporationLedgerRequestInfo,
|
|
364
|
+
entries_by_entity: dict[int, list[dict]],
|
|
365
|
+
processed_entry_ids: set[int],
|
|
366
|
+
entity_ledger_list: list[LedgerEntitySchema],
|
|
367
|
+
) -> list[EntitySchema]:
|
|
368
|
+
"""
|
|
369
|
+
Process the ledger data for auth member entities.
|
|
370
|
+
|
|
371
|
+
This Helper function processes the ledger data for auth member entities
|
|
372
|
+
based on the provided date query.
|
|
373
|
+
|
|
374
|
+
Args:
|
|
375
|
+
entity_ids (set[int]): The set of entity IDs to process.
|
|
376
|
+
entries_by_entity (dict[int, list[dict]]): The mapping of entity IDs to their ledger entries.
|
|
377
|
+
processed_entry_ids (set[int]): The set of already processed ledger entry IDs.
|
|
378
|
+
entity_ledger_list (list[LedgerEntitySchema]): The list to append processed ledger data to.
|
|
379
|
+
Returns:
|
|
380
|
+
list[int]: A list of processed entity IDs.
|
|
381
|
+
"""
|
|
382
|
+
|
|
383
|
+
accounts = UserProfile.objects.filter(
|
|
384
|
+
main_character__isnull=False,
|
|
385
|
+
).order_by(
|
|
386
|
+
"user__profile__main_character__character_name",
|
|
387
|
+
)
|
|
388
|
+
|
|
389
|
+
auth_entity_ids = []
|
|
390
|
+
for account in accounts:
|
|
391
|
+
alts = account.user.character_ownerships.all()
|
|
392
|
+
existings_alts = alts.filter(
|
|
393
|
+
character__character_id__in=entity_ids.intersection(
|
|
394
|
+
alts.values_list("character__character_id", flat=True)
|
|
395
|
+
)
|
|
396
|
+
)
|
|
397
|
+
alt_ids = list(
|
|
398
|
+
existings_alts.values_list("character__character_id", flat=True)
|
|
399
|
+
)
|
|
400
|
+
|
|
401
|
+
# Skip if no characters in Corporation
|
|
402
|
+
if not alt_ids:
|
|
403
|
+
continue
|
|
404
|
+
|
|
405
|
+
response_ledger = self._process_entity_entries(
|
|
406
|
+
entity=EntitySchema(
|
|
407
|
+
entity_id=account.main_character.character_id,
|
|
408
|
+
entity_name=account.main_character.character_name,
|
|
409
|
+
alt_ids=alt_ids,
|
|
410
|
+
icon=get_character_portrait_url(
|
|
411
|
+
character_id=account.main_character.character_id,
|
|
412
|
+
character_name=account.main_character.character_name,
|
|
413
|
+
size=32,
|
|
414
|
+
as_html=True,
|
|
415
|
+
),
|
|
416
|
+
popover=get_corporation_ledger_popover_button(alts=existings_alts),
|
|
417
|
+
),
|
|
418
|
+
request_info=request_info,
|
|
419
|
+
entries_by_entity=entries_by_entity,
|
|
420
|
+
processed_entry_ids=processed_entry_ids,
|
|
421
|
+
)
|
|
422
|
+
auth_entity_ids.extend(alt_ids)
|
|
423
|
+
if response_ledger is None:
|
|
424
|
+
continue
|
|
425
|
+
# Add Entity Ledger to List
|
|
426
|
+
entity_ledger_list.append(response_ledger)
|
|
427
|
+
return auth_entity_ids
|
|
428
|
+
|
|
429
|
+
def _process_ledger_data(
|
|
430
|
+
self,
|
|
431
|
+
entities: list[EveEntity],
|
|
432
|
+
request_info: CorporationLedgerRequestInfo,
|
|
433
|
+
entries_by_entity: dict[int, list[dict]],
|
|
434
|
+
processed_entry_ids: set[int],
|
|
435
|
+
entity_ledger_list: list[LedgerEntitySchema],
|
|
436
|
+
) -> list[LedgerEntitySchema]:
|
|
437
|
+
"""
|
|
438
|
+
Process the ledger data for the given entity IDs.
|
|
439
|
+
|
|
440
|
+
This Helper function processes the ledger data for the given entity IDs
|
|
441
|
+
based on the provided date query.
|
|
442
|
+
|
|
443
|
+
Args:
|
|
444
|
+
entity_ids (list[int]): The list of entity IDs to process.
|
|
445
|
+
entries_by_entity (dict[int, list[dict]]): The mapping of entity IDs to their ledger entries.
|
|
446
|
+
processed_entry_ids (set[int]): The set of already processed ledger entry IDs.
|
|
447
|
+
entity_ledger_list (list[LedgerEntitySchema]): The list to append processed ledger data to.
|
|
448
|
+
Returns:
|
|
449
|
+
list[LedgerEntitySchema]: A list of ledger responses for each entity.
|
|
450
|
+
"""
|
|
451
|
+
for entity in entities:
|
|
452
|
+
response_ledger = self._process_entity_entries(
|
|
453
|
+
entity=EntitySchema(
|
|
454
|
+
entity_id=entity.eve_id,
|
|
455
|
+
entity_name=entity.name,
|
|
456
|
+
icon=entity.get_portrait(size=32, as_html=True),
|
|
457
|
+
),
|
|
458
|
+
request_info=request_info,
|
|
459
|
+
entries_by_entity=entries_by_entity,
|
|
460
|
+
processed_entry_ids=processed_entry_ids,
|
|
461
|
+
)
|
|
462
|
+
if response_ledger is None:
|
|
463
|
+
continue
|
|
464
|
+
# Add Entity Ledger to List
|
|
465
|
+
entity_ledger_list.append(response_ledger)
|
|
466
|
+
|
|
467
|
+
return entity_ledger_list
|
|
468
|
+
|
|
469
|
+
# pylint: disable=too-many-locals
|
|
470
|
+
def generate_entity_data(
|
|
471
|
+
self, owner: CorporationOwner, request_info: CorporationLedgerRequestInfo
|
|
472
|
+
) -> list[CorporationLedgerResponse]:
|
|
473
|
+
"""
|
|
474
|
+
Generate the ledger data for a corporation owner.
|
|
475
|
+
|
|
476
|
+
This Helper function generates the ledger data for a entity
|
|
477
|
+
based on the provided date query.
|
|
478
|
+
|
|
479
|
+
Args:
|
|
480
|
+
owner (CorporationOwner): The corporation owner object.
|
|
481
|
+
request_info (LedgerRequestInfo): The request information object.
|
|
482
|
+
Returns:
|
|
483
|
+
list[CorporationLedgerResponse]: A list of ledger responses for each entity.
|
|
484
|
+
"""
|
|
485
|
+
# Get Corporation Wallet Journal Entries
|
|
486
|
+
corp_journal_values = (
|
|
487
|
+
CorporationWalletJournalEntry.objects.filter(
|
|
488
|
+
division__corporation=owner,
|
|
489
|
+
**request_info.to_date_query(),
|
|
490
|
+
**request_info.to_division_query(),
|
|
491
|
+
)
|
|
492
|
+
# Exclude Zero Amount Entries
|
|
493
|
+
.exclude(amount=Decimal("0.00"))
|
|
494
|
+
# Exclude Internal Transfers
|
|
495
|
+
.exclude(
|
|
496
|
+
first_party_id=owner.eve_corporation.corporation_id,
|
|
497
|
+
second_party_id=owner.eve_corporation.corporation_id,
|
|
498
|
+
)
|
|
499
|
+
.values(
|
|
500
|
+
"entry_id",
|
|
501
|
+
"amount",
|
|
502
|
+
"ref_type",
|
|
503
|
+
"first_party_id",
|
|
504
|
+
"second_party_id",
|
|
505
|
+
"date",
|
|
506
|
+
)
|
|
507
|
+
.order_by("-date")
|
|
508
|
+
)
|
|
509
|
+
|
|
510
|
+
header_ids = list(corp_journal_values.values_list("entry_id", flat=True))
|
|
511
|
+
|
|
512
|
+
# Skip Corporation if no Ledger Entries
|
|
513
|
+
if len(header_ids) == 0:
|
|
514
|
+
return []
|
|
515
|
+
|
|
516
|
+
# Add Owner ID to header ids to ensure uniqueness
|
|
517
|
+
header_ids.append(owner.eve_corporation.corporation_id)
|
|
518
|
+
|
|
519
|
+
# Create Ledger Hash
|
|
520
|
+
wallet_journal_hash = self.cache_manager.create_ledger_hash(header_ids)
|
|
521
|
+
|
|
522
|
+
# Get Cached Ledger if Available
|
|
523
|
+
entity_ledger_list = self.cache_manager.get_cache_key(
|
|
524
|
+
key="corporation", ledger_hash=wallet_journal_hash
|
|
525
|
+
)
|
|
526
|
+
if entity_ledger_list is False:
|
|
527
|
+
entity_ids = set()
|
|
528
|
+
entity_ledger_list: list[LedgerEntitySchema] = []
|
|
529
|
+
processed_entry_ids: set[int] = set()
|
|
530
|
+
entries_by_entity: dict[int, list[dict]] = defaultdict(list)
|
|
531
|
+
|
|
532
|
+
for row in corp_journal_values:
|
|
533
|
+
a = row.get("first_party_id")
|
|
534
|
+
b = row.get("second_party_id")
|
|
535
|
+
if a:
|
|
536
|
+
entries_by_entity[a].append(row)
|
|
537
|
+
entity_ids.add(a)
|
|
538
|
+
|
|
539
|
+
# Only append second party if different from first to avoid double-counting
|
|
540
|
+
if b and b != a:
|
|
541
|
+
entries_by_entity[b].append(row)
|
|
542
|
+
entity_ids.add(b)
|
|
543
|
+
|
|
544
|
+
# Process Auth Entities (Members) First
|
|
545
|
+
auth_entity_ids = self.process_member_ledger_data(
|
|
546
|
+
entity_ids=entity_ids,
|
|
547
|
+
request_info=request_info,
|
|
548
|
+
entries_by_entity=entries_by_entity,
|
|
549
|
+
processed_entry_ids=processed_entry_ids,
|
|
550
|
+
entity_ledger_list=entity_ledger_list,
|
|
551
|
+
)
|
|
552
|
+
|
|
553
|
+
# Process Remaining Entities
|
|
554
|
+
entities = (
|
|
555
|
+
EveEntity.objects.filter(eve_id__in=entity_ids)
|
|
556
|
+
# Exclude Auth Entities
|
|
557
|
+
.exclude(eve_id__in=auth_entity_ids)
|
|
558
|
+
# Exclude NPC Entities
|
|
559
|
+
.exclude(eve_id__in=NPC_ENTITIES)
|
|
560
|
+
# Exclude Corporation Itself
|
|
561
|
+
.exclude(eve_id=owner.eve_corporation.corporation_id).order_by("name")
|
|
562
|
+
)
|
|
563
|
+
|
|
564
|
+
# Process NPC Entities Last
|
|
565
|
+
npc_entities = EveEntity.objects.filter(eve_id__in=NPC_ENTITIES).order_by(
|
|
566
|
+
"name"
|
|
567
|
+
)
|
|
568
|
+
|
|
569
|
+
# Process each Entity
|
|
570
|
+
self._process_ledger_data(
|
|
571
|
+
entities=list(entities),
|
|
572
|
+
request_info=request_info,
|
|
573
|
+
entries_by_entity=entries_by_entity,
|
|
574
|
+
processed_entry_ids=processed_entry_ids,
|
|
575
|
+
entity_ledger_list=entity_ledger_list,
|
|
576
|
+
)
|
|
577
|
+
|
|
578
|
+
# Process NPC Entities
|
|
579
|
+
self._process_ledger_data(
|
|
580
|
+
entities=list(npc_entities),
|
|
581
|
+
request_info=request_info,
|
|
582
|
+
entries_by_entity=entries_by_entity,
|
|
583
|
+
processed_entry_ids=processed_entry_ids,
|
|
584
|
+
entity_ledger_list=entity_ledger_list,
|
|
585
|
+
)
|
|
586
|
+
# Cache Ledger Response
|
|
587
|
+
self.cache_manager.set_cache_key(
|
|
588
|
+
key="corporation",
|
|
589
|
+
ledger_hash=wallet_journal_hash,
|
|
590
|
+
ledger_data=entity_ledger_list,
|
|
591
|
+
)
|
|
592
|
+
return entity_ledger_list
|
|
593
|
+
|
|
594
|
+
def generate_billboard_data(
|
|
595
|
+
self,
|
|
596
|
+
owner: CorporationOwner,
|
|
597
|
+
entity_ledger_list: list[LedgerEntitySchema],
|
|
598
|
+
request_info: CorporationLedgerRequestInfo,
|
|
599
|
+
) -> BillboardSchema:
|
|
600
|
+
"""
|
|
601
|
+
Generate the billboard data for the corporation ledger.
|
|
602
|
+
|
|
603
|
+
This Helper function generates the billboard data for the corporation
|
|
604
|
+
based on the provided character ledger data.
|
|
605
|
+
|
|
606
|
+
Args:
|
|
607
|
+
owner (CorporationOwner): The corporation owner object.
|
|
608
|
+
character_ledger_list (list[LedgerCharacterSchema]): The list of character ledger data.
|
|
609
|
+
request_info (LedgerRequestInfo): The request information object.
|
|
610
|
+
Returns:
|
|
611
|
+
BillboardSchema: The generated billboard data.
|
|
612
|
+
"""
|
|
613
|
+
# Get Wallet Journal Entries
|
|
614
|
+
corp_wallet_journal = (
|
|
615
|
+
CorporationWalletJournalEntry.objects.filter(
|
|
616
|
+
division__corporation=owner,
|
|
617
|
+
**request_info.to_date_query(),
|
|
618
|
+
**request_info.to_division_query(),
|
|
619
|
+
)
|
|
620
|
+
# Exclude Zero Amount Entries
|
|
621
|
+
.exclude(amount=Decimal("0.00"))
|
|
622
|
+
# Exclude Internal Transfers
|
|
623
|
+
.exclude(
|
|
624
|
+
first_party_id=owner.eve_corporation.corporation_id,
|
|
625
|
+
second_party_id=owner.eve_corporation.corporation_id,
|
|
626
|
+
)
|
|
627
|
+
)
|
|
628
|
+
|
|
629
|
+
# Get IDs for Hashing
|
|
630
|
+
header_ids = list(corp_wallet_journal.values_list("entry_id", flat=True))
|
|
631
|
+
|
|
632
|
+
# Skip Corporation if no Ledger Entries
|
|
633
|
+
if len(header_ids) == 0:
|
|
634
|
+
return BillboardSchema()
|
|
635
|
+
|
|
636
|
+
# add corporation id to header ids to ensure uniqueness
|
|
637
|
+
header_ids.append(owner.eve_corporation.corporation_id)
|
|
638
|
+
|
|
639
|
+
# Create Ledger Hash
|
|
640
|
+
wallet_journal_hash = self.cache_manager.create_ledger_hash(header_ids)
|
|
641
|
+
|
|
642
|
+
# Get Cached Billboard if Available
|
|
643
|
+
response_billboard = self.cache_manager.get_cache_key(
|
|
644
|
+
key="corporation-billboard", ledger_hash=wallet_journal_hash
|
|
645
|
+
)
|
|
646
|
+
if response_billboard is False:
|
|
647
|
+
logger.debug(f"Billboard Cache for: {owner}")
|
|
648
|
+
# Create Timelines
|
|
649
|
+
wallet_timeline = (
|
|
650
|
+
self.billboard.create_timeline(
|
|
651
|
+
journal=corp_wallet_journal, request_info=request_info
|
|
652
|
+
)
|
|
653
|
+
.annotate_bounty_income()
|
|
654
|
+
.annotate_ess_income()
|
|
655
|
+
.annotate_miscellaneous()
|
|
656
|
+
)
|
|
657
|
+
|
|
658
|
+
# Generate XY Billboard
|
|
659
|
+
xy_results = self.billboard.create_or_update_results(wallet_timeline)
|
|
660
|
+
xy_billboard = self.billboard.create_xy_billboard(
|
|
661
|
+
results=xy_results, request_info=request_info
|
|
662
|
+
)
|
|
663
|
+
# Initialize Chord Billboard
|
|
664
|
+
chord_billboard = self.billboard.create_chord_billboard(entity_ledger_list)
|
|
665
|
+
|
|
666
|
+
response_billboard = BillboardSchema(
|
|
667
|
+
xy_chart=xy_billboard, chord_chart=chord_billboard
|
|
668
|
+
)
|
|
669
|
+
# Cache Billboard Response
|
|
670
|
+
self.cache_manager.set_cache_key(
|
|
671
|
+
key="corporation-billboard",
|
|
672
|
+
ledger_hash=wallet_journal_hash,
|
|
673
|
+
ledger_data=response_billboard,
|
|
674
|
+
)
|
|
675
|
+
# Billboard Data Generation Logic Here
|
|
676
|
+
return response_billboard
|
|
677
|
+
|
|
678
|
+
# pylint: disable=too-many-positional-arguments, duplicate-code
|
|
679
|
+
def _ledger_api_response(
|
|
680
|
+
self,
|
|
681
|
+
request,
|
|
682
|
+
corporation_id: int,
|
|
683
|
+
year: int,
|
|
684
|
+
division_id: int = None,
|
|
685
|
+
month: int = None,
|
|
686
|
+
day: int = None,
|
|
687
|
+
) -> CorporationLedgerResponse | tuple[int, dict]:
|
|
688
|
+
"""
|
|
689
|
+
Helper function to generate ledger response for various date parameters.
|
|
690
|
+
|
|
691
|
+
This function consolidates the common logic for generating the ledger response
|
|
692
|
+
based on the provided date parameters (year, month, day).
|
|
693
|
+
|
|
694
|
+
Args:
|
|
695
|
+
request (WSGIRequest): The incoming request object.
|
|
696
|
+
corporation_id (int): The corporation ID.
|
|
697
|
+
year (int): The year for the ledger data.
|
|
698
|
+
month (int, optional): The month for the ledger data. Defaults to None.
|
|
699
|
+
day (int, optional): The day for the ledger data. Defaults to None.
|
|
700
|
+
|
|
701
|
+
Returns:
|
|
702
|
+
CorporationLedgerResponse | tuple[int, dict]: The ledger response or error tuple.
|
|
703
|
+
"""
|
|
704
|
+
perms, owner = get_corporationowner_or_none(
|
|
705
|
+
request=request, corporation_id=corporation_id
|
|
706
|
+
)
|
|
707
|
+
|
|
708
|
+
if owner is None:
|
|
709
|
+
return 404, {"error": _("Corporation not found in Ledger.")}
|
|
710
|
+
|
|
711
|
+
if perms is False:
|
|
712
|
+
return 403, {
|
|
713
|
+
"error": _("You do not have permission to view this corporation.")
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
# Build Request Info
|
|
717
|
+
request_info = CorporationLedgerRequestInfo(
|
|
718
|
+
owner_id=owner.eve_corporation.corporation_id,
|
|
719
|
+
division_id=division_id,
|
|
720
|
+
year=year,
|
|
721
|
+
month=month,
|
|
722
|
+
day=day,
|
|
723
|
+
)
|
|
724
|
+
|
|
725
|
+
# Generate Entity Ledger Data
|
|
726
|
+
entity_ledger_list = self.generate_entity_data(
|
|
727
|
+
owner=owner,
|
|
728
|
+
request_info=request_info,
|
|
729
|
+
)
|
|
730
|
+
|
|
731
|
+
# Generate Billboard Data
|
|
732
|
+
billboard = self.generate_billboard_data(
|
|
733
|
+
owner=owner,
|
|
734
|
+
entity_ledger_list=entity_ledger_list,
|
|
735
|
+
request_info=request_info,
|
|
736
|
+
)
|
|
737
|
+
|
|
738
|
+
# Update Request Info with Available Data
|
|
739
|
+
self._create_datatable_footer(
|
|
740
|
+
entities=entity_ledger_list, request_info=request_info
|
|
741
|
+
)
|
|
742
|
+
|
|
743
|
+
response_ledger = CorporationLedgerResponse(
|
|
744
|
+
owner=OwnerSchema(
|
|
745
|
+
character_id=owner.eve_corporation.corporation_id,
|
|
746
|
+
character_name=owner.eve_corporation.corporation_name,
|
|
747
|
+
icon=owner.get_portrait(as_html=True),
|
|
748
|
+
),
|
|
749
|
+
information=request_info,
|
|
750
|
+
entities=entity_ledger_list,
|
|
751
|
+
billboard=billboard,
|
|
752
|
+
actions=get_corporation_details_info_button(
|
|
753
|
+
entity_id=owner.eve_corporation.corporation_id,
|
|
754
|
+
request_info=request_info,
|
|
755
|
+
),
|
|
756
|
+
)
|
|
757
|
+
|
|
758
|
+
return response_ledger
|
|
759
|
+
|
|
760
|
+
|
|
761
|
+
class CorporationDetailsApiEndpoints:
|
|
762
|
+
tags = ["Corporation Details"]
|
|
763
|
+
|
|
764
|
+
# pylint: disable=too-many-statements, function-redefined, too-many-arguments
|
|
765
|
+
def __init__(self, api: NinjaAPI):
|
|
766
|
+
@api.get(
|
|
767
|
+
"corporation/{corporation_id}/division/{division_id}/date/{year}/section/{section}/view/details/{entity_id}/",
|
|
768
|
+
response={200: LedgerDetailsResponse, 403: dict, 404: dict},
|
|
769
|
+
tags=self.tags,
|
|
770
|
+
)
|
|
771
|
+
def get_corporation_ledger_details(
|
|
772
|
+
request: WSGIRequest,
|
|
773
|
+
corporation_id: int,
|
|
774
|
+
division_id: int,
|
|
775
|
+
year: int,
|
|
776
|
+
section: str,
|
|
777
|
+
entity_id: int,
|
|
778
|
+
):
|
|
779
|
+
return self._ledger_details_api_response(
|
|
780
|
+
request=request,
|
|
781
|
+
corporation_id=corporation_id,
|
|
782
|
+
division_id=division_id,
|
|
783
|
+
entity_id=entity_id,
|
|
784
|
+
year=year,
|
|
785
|
+
section=section,
|
|
786
|
+
)
|
|
787
|
+
|
|
788
|
+
@api.get(
|
|
789
|
+
"corporation/{corporation_id}/division/{division_id}/date/{year}/{month}/section/{section}/view/details/{entity_id}/",
|
|
790
|
+
response={200: LedgerDetailsResponse, 403: dict, 404: dict},
|
|
791
|
+
tags=self.tags,
|
|
792
|
+
)
|
|
793
|
+
# pylint: disable=too-many-positional-arguments
|
|
794
|
+
def get_corporation_ledger_details(
|
|
795
|
+
request: WSGIRequest,
|
|
796
|
+
corporation_id: int,
|
|
797
|
+
division_id: int,
|
|
798
|
+
year: int,
|
|
799
|
+
month: int,
|
|
800
|
+
section: str,
|
|
801
|
+
entity_id: int,
|
|
802
|
+
):
|
|
803
|
+
return self._ledger_details_api_response(
|
|
804
|
+
request=request,
|
|
805
|
+
corporation_id=corporation_id,
|
|
806
|
+
division_id=division_id,
|
|
807
|
+
entity_id=entity_id,
|
|
808
|
+
year=year,
|
|
809
|
+
month=month,
|
|
810
|
+
section=section,
|
|
811
|
+
)
|
|
812
|
+
|
|
813
|
+
@api.get(
|
|
814
|
+
"corporation/{corporation_id}/division/{division_id}/date/{year}/{month}/{day}/section/{section}/view/details/{entity_id}/",
|
|
815
|
+
response={200: LedgerDetailsResponse, 403: dict, 404: dict},
|
|
816
|
+
tags=self.tags,
|
|
817
|
+
)
|
|
818
|
+
# pylint: disable=too-many-positional-arguments
|
|
819
|
+
def get_corporation_ledger_details(
|
|
820
|
+
request: WSGIRequest,
|
|
821
|
+
corporation_id: int,
|
|
822
|
+
division_id: int,
|
|
823
|
+
year: int,
|
|
824
|
+
month: int,
|
|
825
|
+
day: int,
|
|
826
|
+
section: str,
|
|
827
|
+
entity_id: int,
|
|
828
|
+
):
|
|
829
|
+
return self._ledger_details_api_response(
|
|
830
|
+
request=request,
|
|
831
|
+
corporation_id=corporation_id,
|
|
832
|
+
division_id=division_id,
|
|
833
|
+
entity_id=entity_id,
|
|
834
|
+
year=year,
|
|
835
|
+
month=month,
|
|
836
|
+
day=day,
|
|
837
|
+
section=section,
|
|
838
|
+
)
|
|
839
|
+
|
|
840
|
+
@api.get(
|
|
841
|
+
"corporation/{corporation_id}/date/{year}/section/{section}/view/details/{entity_id}/",
|
|
842
|
+
response={200: LedgerDetailsResponse, 403: dict, 404: dict},
|
|
843
|
+
tags=self.tags,
|
|
844
|
+
)
|
|
845
|
+
def get_corporation_ledger_details(
|
|
846
|
+
request: WSGIRequest,
|
|
847
|
+
corporation_id: int,
|
|
848
|
+
year: int,
|
|
849
|
+
section: str,
|
|
850
|
+
entity_id: int,
|
|
851
|
+
):
|
|
852
|
+
return self._ledger_details_api_response(
|
|
853
|
+
request=request,
|
|
854
|
+
corporation_id=corporation_id,
|
|
855
|
+
entity_id=entity_id,
|
|
856
|
+
year=year,
|
|
857
|
+
section=section,
|
|
858
|
+
)
|
|
859
|
+
|
|
860
|
+
@api.get(
|
|
861
|
+
"corporation/{corporation_id}/date/{year}/{month}/section/{section}/view/details/{entity_id}/",
|
|
862
|
+
response={200: LedgerDetailsResponse, 403: dict, 404: dict},
|
|
863
|
+
tags=self.tags,
|
|
864
|
+
)
|
|
865
|
+
def get_corporation_ledger_details(
|
|
866
|
+
request: WSGIRequest,
|
|
867
|
+
corporation_id: int,
|
|
868
|
+
year: int,
|
|
869
|
+
month: int,
|
|
870
|
+
section: str,
|
|
871
|
+
entity_id: int,
|
|
872
|
+
):
|
|
873
|
+
return self._ledger_details_api_response(
|
|
874
|
+
request=request,
|
|
875
|
+
corporation_id=corporation_id,
|
|
876
|
+
entity_id=entity_id,
|
|
877
|
+
year=year,
|
|
878
|
+
month=month,
|
|
879
|
+
section=section,
|
|
880
|
+
)
|
|
881
|
+
|
|
882
|
+
@api.get(
|
|
883
|
+
"corporation/{corporation_id}/date/{year}/{month}/{day}/section/{section}/view/details/{entity_id}/",
|
|
884
|
+
response={200: LedgerDetailsResponse, 403: dict, 404: dict},
|
|
885
|
+
tags=self.tags,
|
|
886
|
+
)
|
|
887
|
+
# pylint: disable=too-many-positional-arguments
|
|
888
|
+
def get_corporation_ledger_details(
|
|
889
|
+
request: WSGIRequest,
|
|
890
|
+
corporation_id: int,
|
|
891
|
+
year: int,
|
|
892
|
+
month: int,
|
|
893
|
+
day: int,
|
|
894
|
+
section: str,
|
|
895
|
+
entity_id: int,
|
|
896
|
+
):
|
|
897
|
+
return self._ledger_details_api_response(
|
|
898
|
+
request=request,
|
|
899
|
+
corporation_id=corporation_id,
|
|
900
|
+
entity_id=entity_id,
|
|
901
|
+
year=year,
|
|
902
|
+
month=month,
|
|
903
|
+
day=day,
|
|
904
|
+
section=section,
|
|
905
|
+
)
|
|
906
|
+
|
|
907
|
+
# pylint: disable=duplicate-code
|
|
908
|
+
def _create_datatable_footer(self, value: float) -> str:
|
|
909
|
+
"""Create the footer HTML for the datatable."""
|
|
910
|
+
footer_html = f"""
|
|
911
|
+
<tr>
|
|
912
|
+
<th>{_('Summary')}</th>
|
|
913
|
+
<th class="text-end {get_footer_text_class(value)}">{intcomma(value=int(value), use_l10n=True)} ISK</th>
|
|
914
|
+
<th></th>
|
|
915
|
+
</tr>
|
|
916
|
+
"""
|
|
917
|
+
return footer_html
|
|
918
|
+
|
|
919
|
+
# pylint: disable=too-many-locals
|
|
920
|
+
def _create_ledger_details(
|
|
921
|
+
self,
|
|
922
|
+
journal: QuerySet[CorporationWalletJournalEntry],
|
|
923
|
+
request_info: CorporationLedgerRequestInfo,
|
|
924
|
+
) -> LedgerDetailsResponse:
|
|
925
|
+
"""
|
|
926
|
+
Generate the detailed ledger data for a character.
|
|
927
|
+
This Helper function generates the detailed ledger data for a character
|
|
928
|
+
based on the provided date query.
|
|
929
|
+
|
|
930
|
+
Args:
|
|
931
|
+
journal (QuerySet): The wallet journal entries.
|
|
932
|
+
mining (QuerySet): The mining ledger entries. Defaults to None.
|
|
933
|
+
request_info (LedgerRequestInfo): The request information containing date and section details.
|
|
934
|
+
Returns:
|
|
935
|
+
LedgerDetailsResponse: The generated ledger details response.
|
|
936
|
+
"""
|
|
937
|
+
ref_types = RefTypeManager.get_all_categories()
|
|
938
|
+
|
|
939
|
+
avg = request_info.day if request_info.day else timezone.now().day
|
|
940
|
+
if request_info.section == "summary":
|
|
941
|
+
avg = 365
|
|
942
|
+
|
|
943
|
+
monthly_list = []
|
|
944
|
+
daily_list = []
|
|
945
|
+
hourly_list = []
|
|
946
|
+
summary = 0
|
|
947
|
+
# Income/Cost Ref Types
|
|
948
|
+
for category in RefTypeManager.CategoryChoice:
|
|
949
|
+
category_ref_types = ref_types.get(category.value, [])
|
|
950
|
+
if not category_ref_types:
|
|
951
|
+
continue
|
|
952
|
+
for __, income_flag in (("income", True), ("cost", False)):
|
|
953
|
+
kind_label = _("Income from") if income_flag else _("Cost from")
|
|
954
|
+
name = _("%(kind)s %(category)s") % {
|
|
955
|
+
"category": category.label,
|
|
956
|
+
"kind": kind_label,
|
|
957
|
+
}
|
|
958
|
+
kwargs = {"ref_type": category_ref_types, "income": income_flag}
|
|
959
|
+
amount = journal.aggregate_ref_type(**kwargs)
|
|
960
|
+
if (income_flag and amount > 0) or (not income_flag and amount < 0):
|
|
961
|
+
monthly = CategorySchema(
|
|
962
|
+
name=name,
|
|
963
|
+
amount=amount,
|
|
964
|
+
average=amount / avg / 30,
|
|
965
|
+
average_tick=amount / avg / 30 / 20,
|
|
966
|
+
ref_types=get_ref_type_details_popover_button(
|
|
967
|
+
ref_types=category_ref_types
|
|
968
|
+
),
|
|
969
|
+
)
|
|
970
|
+
|
|
971
|
+
daily = CategorySchema(
|
|
972
|
+
name=name,
|
|
973
|
+
amount=amount / avg,
|
|
974
|
+
average=amount / avg / 30,
|
|
975
|
+
average_tick=amount / avg / 20,
|
|
976
|
+
ref_types=get_ref_type_details_popover_button(
|
|
977
|
+
ref_types=category_ref_types
|
|
978
|
+
),
|
|
979
|
+
)
|
|
980
|
+
|
|
981
|
+
hourly = CategorySchema(
|
|
982
|
+
name=name,
|
|
983
|
+
amount=amount / avg / 24,
|
|
984
|
+
average=amount / avg / 24 / 30,
|
|
985
|
+
average_tick=amount / avg / 24 / 20,
|
|
986
|
+
ref_types=get_ref_type_details_popover_button(
|
|
987
|
+
ref_types=category_ref_types
|
|
988
|
+
),
|
|
989
|
+
)
|
|
990
|
+
# Add Amounts
|
|
991
|
+
summary += amount
|
|
992
|
+
monthly_list.append(monthly)
|
|
993
|
+
daily_list.append(daily)
|
|
994
|
+
hourly_list.append(hourly)
|
|
995
|
+
|
|
996
|
+
if summary == 0:
|
|
997
|
+
return None
|
|
998
|
+
|
|
999
|
+
return LedgerDetailsResponse(
|
|
1000
|
+
summary=monthly_list,
|
|
1001
|
+
daily=daily_list,
|
|
1002
|
+
hourly=hourly_list,
|
|
1003
|
+
total=LedgerDetailsSummary(
|
|
1004
|
+
summary=self._create_datatable_footer(summary),
|
|
1005
|
+
daily=self._create_datatable_footer(
|
|
1006
|
+
summary / avg,
|
|
1007
|
+
),
|
|
1008
|
+
hourly=self._create_datatable_footer(
|
|
1009
|
+
summary / avg / 24,
|
|
1010
|
+
),
|
|
1011
|
+
),
|
|
1012
|
+
)
|
|
1013
|
+
|
|
1014
|
+
def _check_auth_account(
|
|
1015
|
+
self,
|
|
1016
|
+
owner: CorporationOwner,
|
|
1017
|
+
entity_id: int,
|
|
1018
|
+
) -> list[int] | None:
|
|
1019
|
+
"""
|
|
1020
|
+
Check if the entity_id belongs to a auth account of the corporation.
|
|
1021
|
+
"""
|
|
1022
|
+
for member in owner.auth_accounts:
|
|
1023
|
+
alt_ids = list(
|
|
1024
|
+
member.user.character_ownerships.all().values_list(
|
|
1025
|
+
"character__character_id", flat=True
|
|
1026
|
+
)
|
|
1027
|
+
)
|
|
1028
|
+
if entity_id in alt_ids:
|
|
1029
|
+
return alt_ids
|
|
1030
|
+
return None
|
|
1031
|
+
|
|
1032
|
+
def create_entity_details(
|
|
1033
|
+
self,
|
|
1034
|
+
owner: CorporationOwner,
|
|
1035
|
+
entity_id: int,
|
|
1036
|
+
request_info: CorporationLedgerRequestInfo,
|
|
1037
|
+
) -> dict:
|
|
1038
|
+
"""
|
|
1039
|
+
Create the entity amounts for the Information View.
|
|
1040
|
+
"""
|
|
1041
|
+
# Check if Entity is a Member
|
|
1042
|
+
alt_ids = self._check_auth_account(owner=owner, entity_id=entity_id)
|
|
1043
|
+
|
|
1044
|
+
# Build Entity Query
|
|
1045
|
+
entity_query = Q(first_party_id=entity_id) | Q(second_party_id=entity_id)
|
|
1046
|
+
if alt_ids is not None:
|
|
1047
|
+
# If Member, query all alt_ids
|
|
1048
|
+
entity_query = Q(first_party_id__in=alt_ids) | Q(
|
|
1049
|
+
second_party_id__in=alt_ids
|
|
1050
|
+
)
|
|
1051
|
+
elif entity_id == owner.eve_corporation.corporation_id:
|
|
1052
|
+
# If Corporation itself query all entries
|
|
1053
|
+
entity_query = Q()
|
|
1054
|
+
|
|
1055
|
+
# Get Wallet Journal Entries
|
|
1056
|
+
wallet_journal = (
|
|
1057
|
+
CorporationWalletJournalEntry.objects.filter(
|
|
1058
|
+
entity_query,
|
|
1059
|
+
division__corporation=owner,
|
|
1060
|
+
**request_info.to_date_query(),
|
|
1061
|
+
**request_info.to_division_query(),
|
|
1062
|
+
)
|
|
1063
|
+
# Exclude Zero Amount Entries
|
|
1064
|
+
.exclude(amount=Decimal("0.00"))
|
|
1065
|
+
# Exclude Internal Transfers
|
|
1066
|
+
.exclude(
|
|
1067
|
+
first_party_id=owner.eve_corporation.corporation_id,
|
|
1068
|
+
second_party_id=owner.eve_corporation.corporation_id,
|
|
1069
|
+
)
|
|
1070
|
+
)
|
|
1071
|
+
|
|
1072
|
+
# If Member, Exclude Corporation Contracts (will count in Corporation itself)
|
|
1073
|
+
if alt_ids is not None:
|
|
1074
|
+
wallet_journal = wallet_journal.exclude(
|
|
1075
|
+
ref_type="contract_price_payment_corp",
|
|
1076
|
+
second_party_id__in=alt_ids,
|
|
1077
|
+
)
|
|
1078
|
+
|
|
1079
|
+
response_ledger_details: LedgerDetailsResponse = self._create_ledger_details(
|
|
1080
|
+
journal=wallet_journal,
|
|
1081
|
+
request_info=request_info,
|
|
1082
|
+
)
|
|
1083
|
+
return response_ledger_details
|
|
1084
|
+
|
|
1085
|
+
# pylint: disable=too-many-arguments, too-many-positional-arguments
|
|
1086
|
+
def _ledger_details_api_response(
|
|
1087
|
+
self,
|
|
1088
|
+
request: WSGIRequest,
|
|
1089
|
+
corporation_id: int,
|
|
1090
|
+
entity_id: int,
|
|
1091
|
+
year: int,
|
|
1092
|
+
month: int = None,
|
|
1093
|
+
day: int = None,
|
|
1094
|
+
division_id: int = None,
|
|
1095
|
+
section: str = "summary",
|
|
1096
|
+
):
|
|
1097
|
+
"""
|
|
1098
|
+
Helper function to generate ledger details response for various date parameters.
|
|
1099
|
+
|
|
1100
|
+
This function consolidates the common logic for generating the ledger details response
|
|
1101
|
+
based on the provided date parameters character_id, (year, month, day) and section.
|
|
1102
|
+
|
|
1103
|
+
Args:
|
|
1104
|
+
request (WSGIRequest): The incoming request object.
|
|
1105
|
+
corporation_id (int): The corporation ID.
|
|
1106
|
+
entity_id (int): The entity ID.
|
|
1107
|
+
year (int): The year for the ledger data.
|
|
1108
|
+
month (int, optional): The month for the ledger data. Defaults to None.
|
|
1109
|
+
day (int, optional): The day for the ledger data. Defaults to None.
|
|
1110
|
+
division_id (int, optional): The division ID for the ledger data. Defaults to None.
|
|
1111
|
+
section (str): The section type ('single' or 'summary').
|
|
1112
|
+
Returns:
|
|
1113
|
+
LedgerDetailsResponse | tuple[int, dict]: The ledger details response or error tuple.
|
|
1114
|
+
"""
|
|
1115
|
+
perms, owner = get_corporationowner_or_none(
|
|
1116
|
+
request=request, corporation_id=corporation_id
|
|
1117
|
+
)
|
|
1118
|
+
|
|
1119
|
+
if owner is None:
|
|
1120
|
+
return 404, {"error": _("Corporation not found in Ledger.")}
|
|
1121
|
+
|
|
1122
|
+
if perms is False:
|
|
1123
|
+
return 403, {
|
|
1124
|
+
"error": _("You do not have permission to view this corporation.")
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
request_info = CorporationLedgerRequestInfo(
|
|
1128
|
+
owner_id=owner.eve_corporation.corporation_id,
|
|
1129
|
+
entity_id=entity_id,
|
|
1130
|
+
division_id=division_id,
|
|
1131
|
+
year=year,
|
|
1132
|
+
month=month,
|
|
1133
|
+
day=day,
|
|
1134
|
+
section=section,
|
|
1135
|
+
)
|
|
1136
|
+
|
|
1137
|
+
return self.create_entity_details(
|
|
1138
|
+
owner=owner,
|
|
1139
|
+
entity_id=entity_id,
|
|
1140
|
+
request_info=request_info,
|
|
1141
|
+
)
|