aa-ledger 1.0.3__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.3.dist-info → aa_ledger-2.0.0.dist-info}/METADATA +6 -6
- aa_ledger-2.0.0.dist-info/RECORD +267 -0
- {aa_ledger-1.0.3.dist-info → aa_ledger-2.0.0.dist-info}/WHEEL +1 -1
- 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 +18 -26
- 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 +717 -553
- 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 +187 -358
- ledger/managers/character_mining_manager.py +64 -30
- ledger/managers/character_planetary_manager.py +185 -138
- ledger/managers/corporation_audit_manager.py +36 -27
- ledger/managers/corporation_journal_manager.py +94 -57
- ledger/managers/general_manager.py +12 -8
- 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 -146
- 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.3.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.3.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
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# Standard Library
|
|
2
|
+
from decimal import Decimal
|
|
2
3
|
from typing import TYPE_CHECKING
|
|
3
4
|
|
|
4
5
|
# Django
|
|
@@ -10,14 +11,13 @@ from django.db.models.functions import Coalesce
|
|
|
10
11
|
from allianceauth.services.hooks import get_extension_logger
|
|
11
12
|
from esi.errors import TokenError
|
|
12
13
|
|
|
13
|
-
# Alliance Auth (External Libs)
|
|
14
|
-
from app_utils.logging import LoggerAddTag
|
|
15
|
-
|
|
16
14
|
# AA Ledger
|
|
17
15
|
from ledger import __title__
|
|
16
|
+
from ledger.app_settings import LEDGER_BULK_BATCH_SIZE
|
|
18
17
|
from ledger.decorators import log_timing
|
|
19
18
|
from ledger.helpers.ref_type import RefTypeManager
|
|
20
|
-
from ledger.
|
|
19
|
+
from ledger.models.helpers.update_manager import CharacterUpdateSection
|
|
20
|
+
from ledger.providers import AppLogger, esi
|
|
21
21
|
|
|
22
22
|
if TYPE_CHECKING:
|
|
23
23
|
# Alliance Auth
|
|
@@ -25,12 +25,15 @@ if TYPE_CHECKING:
|
|
|
25
25
|
|
|
26
26
|
# AA Ledger
|
|
27
27
|
from ledger.models.characteraudit import (
|
|
28
|
-
|
|
28
|
+
CharacterOwner,
|
|
29
|
+
)
|
|
30
|
+
from ledger.models.characteraudit import (
|
|
31
|
+
CharacterWalletJournalEntry as CharacterWalletJournalEntryContext,
|
|
29
32
|
)
|
|
30
33
|
from ledger.models.general import UpdateSectionResult
|
|
31
34
|
|
|
32
35
|
|
|
33
|
-
logger =
|
|
36
|
+
logger = AppLogger(get_extension_logger(__name__), __title__)
|
|
34
37
|
|
|
35
38
|
|
|
36
39
|
class CharWalletIncomeFilter(models.QuerySet):
|
|
@@ -59,308 +62,244 @@ class CharWalletIncomeFilter(models.QuerySet):
|
|
|
59
62
|
)
|
|
60
63
|
)
|
|
61
64
|
|
|
62
|
-
def annotate_mission_income(self) -> models.QuerySet:
|
|
63
|
-
return self.annotate(
|
|
64
|
-
mission_income=Coalesce(
|
|
65
|
-
Sum(
|
|
66
|
-
"amount",
|
|
67
|
-
filter=Q(ref_type__in=RefTypeManager.MISSION_REWARD, amount__gt=0),
|
|
68
|
-
),
|
|
69
|
-
Value(0),
|
|
70
|
-
output_field=DecimalField(),
|
|
71
|
-
)
|
|
72
|
-
)
|
|
73
65
|
|
|
74
|
-
|
|
66
|
+
class CharWalletOutSideFilter(CharWalletIncomeFilter):
|
|
67
|
+
def annotate_miscellaneous(self) -> models.QuerySet:
|
|
75
68
|
return self.annotate(
|
|
76
|
-
|
|
69
|
+
miscellaneous=Coalesce(
|
|
77
70
|
Sum(
|
|
78
71
|
"amount",
|
|
79
|
-
filter=Q(
|
|
72
|
+
filter=Q(
|
|
73
|
+
ref_type__in=RefTypeManager.ledger_ref_types(), amount__gt=0
|
|
74
|
+
),
|
|
80
75
|
),
|
|
81
76
|
Value(0),
|
|
82
77
|
output_field=DecimalField(),
|
|
83
78
|
)
|
|
84
79
|
)
|
|
85
80
|
|
|
86
|
-
|
|
87
|
-
def annotate_market_income(self) -> models.QuerySet:
|
|
81
|
+
def annotate_costs(self) -> models.QuerySet:
|
|
88
82
|
return self.annotate(
|
|
89
|
-
|
|
83
|
+
costs=Coalesce(
|
|
90
84
|
Sum(
|
|
91
85
|
"amount",
|
|
92
|
-
filter=Q(
|
|
86
|
+
filter=Q(
|
|
87
|
+
ref_type__in=RefTypeManager.ledger_ref_types(), amount__lt=0
|
|
88
|
+
),
|
|
93
89
|
),
|
|
94
90
|
Value(0),
|
|
95
91
|
output_field=DecimalField(),
|
|
96
92
|
)
|
|
97
93
|
)
|
|
98
94
|
|
|
99
|
-
def annotate_contract_income(self) -> models.QuerySet:
|
|
100
|
-
contract_types = list(RefTypeManager.CONTRACT) + list(
|
|
101
|
-
RefTypeManager.CORPORATION_CONTRACT
|
|
102
|
-
)
|
|
103
|
-
return self.annotate(
|
|
104
|
-
contract_income=Coalesce(
|
|
105
|
-
Sum(
|
|
106
|
-
"amount",
|
|
107
|
-
filter=Q(ref_type__in=contract_types, amount__gt=0),
|
|
108
|
-
),
|
|
109
|
-
Value(0),
|
|
110
|
-
output_field=DecimalField(),
|
|
111
|
-
)
|
|
112
|
-
)
|
|
113
95
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
exclude = []
|
|
96
|
+
class CharWalletCostQueryFilter(CharWalletOutSideFilter):
|
|
97
|
+
pass
|
|
117
98
|
|
|
118
|
-
return self.annotate(
|
|
119
|
-
donation_income=Coalesce(
|
|
120
|
-
Sum(
|
|
121
|
-
"amount",
|
|
122
|
-
filter=Q(ref_type__in=RefTypeManager.DONATION, amount__gt=0)
|
|
123
|
-
& ~Q(first_party_id__in=exclude),
|
|
124
|
-
),
|
|
125
|
-
Value(0),
|
|
126
|
-
output_field=DecimalField(),
|
|
127
|
-
)
|
|
128
|
-
)
|
|
129
99
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
)
|
|
100
|
+
# pylint: disable=used-before-assignment
|
|
101
|
+
class CharWalletQuerySet(CharWalletCostQueryFilter):
|
|
102
|
+
def aggregate_bounty(self) -> dict:
|
|
103
|
+
"""Aggregate bounty income."""
|
|
104
|
+
return Decimal(
|
|
105
|
+
self.filter(ref_type__in=RefTypeManager.BOUNTY_PRIZES).aggregate(
|
|
106
|
+
total_bounty=Coalesce(
|
|
107
|
+
Sum("amount"), Value(0), output_field=DecimalField()
|
|
108
|
+
)
|
|
109
|
+
)["total_bounty"]
|
|
140
110
|
)
|
|
141
111
|
|
|
142
|
-
def
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
ref_type__in=RefTypeManager.MILESTONE_REWARD, amount__gt=0
|
|
149
|
-
),
|
|
150
|
-
),
|
|
151
|
-
Value(0),
|
|
152
|
-
output_field=DecimalField(),
|
|
153
|
-
)
|
|
112
|
+
def aggregate_ess(self) -> dict:
|
|
113
|
+
"""Aggregate ESS income."""
|
|
114
|
+
return Decimal(
|
|
115
|
+
self.filter(ref_type__in=RefTypeManager.ESS_TRANSFER).aggregate(
|
|
116
|
+
total_ess=Coalesce(Sum("amount"), Value(0), output_field=DecimalField())
|
|
117
|
+
)["total_ess"]
|
|
154
118
|
)
|
|
155
119
|
|
|
156
|
-
def
|
|
157
|
-
"""
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
)
|
|
169
|
-
)
|
|
120
|
+
def aggregate_costs(self, first_party=None, second_party=None) -> dict:
|
|
121
|
+
"""
|
|
122
|
+
Aggregate costs.
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
first_party (int | list[int], optional): Filter by first party ID(s).
|
|
126
|
+
second_party (int | list[int], optional): Filter by second party ID(s).
|
|
127
|
+
Returns:
|
|
128
|
+
dict: Aggregated total costs.
|
|
129
|
+
"""
|
|
130
|
+
qs = self
|
|
131
|
+
cost_types = RefTypeManager.ledger_ref_types()
|
|
170
132
|
|
|
133
|
+
if first_party is not None:
|
|
134
|
+
if isinstance(first_party, int):
|
|
135
|
+
first_party = [first_party]
|
|
136
|
+
qs = qs.filter(first_party__in=first_party)
|
|
171
137
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
filter=Q(ref_type__in=RefTypeManager.all_ref_types(), amount__gt=0),
|
|
179
|
-
),
|
|
180
|
-
Value(0),
|
|
181
|
-
output_field=DecimalField(),
|
|
182
|
-
)
|
|
183
|
-
)
|
|
138
|
+
if second_party is not None:
|
|
139
|
+
if isinstance(second_party, int):
|
|
140
|
+
second_party = [second_party]
|
|
141
|
+
qs = qs.filter(Q(ref_type__in=cost_types))
|
|
142
|
+
else:
|
|
143
|
+
qs = qs.filter(Q(ref_type__in=cost_types))
|
|
184
144
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
145
|
+
qs = qs.filter(amount__lt=0)
|
|
146
|
+
return Decimal(
|
|
147
|
+
qs.aggregate(
|
|
148
|
+
total_costs=Coalesce(
|
|
149
|
+
Sum("amount"), Value(0), output_field=DecimalField()
|
|
150
|
+
)
|
|
151
|
+
)["total_costs"]
|
|
152
|
+
)
|
|
190
153
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
154
|
+
def aggregate_miscellaneous(self, first_party=None, second_party=None) -> dict:
|
|
155
|
+
"""
|
|
156
|
+
Aggregate miscellaneous income.
|
|
157
|
+
|
|
158
|
+
Args:
|
|
159
|
+
first_party (int | list[int], optional): Filter by first party ID(s).
|
|
160
|
+
second_party (int | list[int], optional): Filter by second party ID(s).
|
|
161
|
+
Returns:
|
|
162
|
+
dict: Aggregated total miscellaneous income.
|
|
163
|
+
"""
|
|
164
|
+
qs = self
|
|
194
165
|
|
|
195
|
-
|
|
196
|
-
try:
|
|
197
|
-
all_types.remove("player_donation")
|
|
198
|
-
except ValueError:
|
|
199
|
-
pass
|
|
166
|
+
misc_types = RefTypeManager.ledger_ref_types()
|
|
200
167
|
|
|
201
|
-
|
|
202
|
-
|
|
168
|
+
if first_party is not None:
|
|
169
|
+
if isinstance(first_party, int):
|
|
170
|
+
first_party = [first_party]
|
|
171
|
+
qs = qs.filter(Q(ref_type__in=misc_types))
|
|
172
|
+
else:
|
|
173
|
+
qs = qs.filter(Q(ref_type__in=misc_types))
|
|
203
174
|
|
|
204
|
-
if
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
)
|
|
175
|
+
if second_party is not None:
|
|
176
|
+
if isinstance(second_party, int):
|
|
177
|
+
second_party = [second_party]
|
|
178
|
+
qs = qs.filter(second_party__in=second_party)
|
|
208
179
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
)
|
|
215
|
-
|
|
216
|
-
output_field=DecimalField(),
|
|
217
|
-
)
|
|
180
|
+
qs = qs.filter(amount__gt=0)
|
|
181
|
+
return Decimal(
|
|
182
|
+
qs.aggregate(
|
|
183
|
+
total_misc=Coalesce(
|
|
184
|
+
Sum("amount"), Value(0), output_field=DecimalField()
|
|
185
|
+
)
|
|
186
|
+
)["total_misc"]
|
|
218
187
|
)
|
|
219
188
|
|
|
220
|
-
def
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
)
|
|
230
|
-
)
|
|
189
|
+
def aggregate_ref_type(
|
|
190
|
+
self,
|
|
191
|
+
ref_type: list,
|
|
192
|
+
first_party=None,
|
|
193
|
+
second_party=None,
|
|
194
|
+
income: bool = False,
|
|
195
|
+
) -> dict:
|
|
196
|
+
"""Aggregate income by ref_type."""
|
|
197
|
+
qs = self.filter(ref_type__in=ref_type)
|
|
231
198
|
|
|
199
|
+
if first_party is not None:
|
|
200
|
+
if isinstance(first_party, int):
|
|
201
|
+
first_party = [first_party]
|
|
202
|
+
qs = qs.filter(first_party__in=first_party)
|
|
232
203
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
contract_cost=Coalesce(
|
|
238
|
-
Sum(
|
|
239
|
-
"amount",
|
|
240
|
-
filter=Q(ref_type__in=RefTypeManager.CONTRACT, amount__lt=0),
|
|
241
|
-
),
|
|
242
|
-
Value(0),
|
|
243
|
-
output_field=DecimalField(),
|
|
244
|
-
)
|
|
245
|
-
)
|
|
204
|
+
if second_party is not None:
|
|
205
|
+
if isinstance(second_party, int):
|
|
206
|
+
second_party = [second_party]
|
|
207
|
+
qs = qs.filter(second_party__in=second_party)
|
|
246
208
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
"amount",
|
|
252
|
-
filter=Q(ref_type__in=RefTypeManager.MARKET, amount__lt=0),
|
|
253
|
-
),
|
|
254
|
-
Value(0),
|
|
255
|
-
output_field=DecimalField(),
|
|
256
|
-
)
|
|
257
|
-
)
|
|
209
|
+
if income:
|
|
210
|
+
qs = qs.filter(amount__gt=0)
|
|
211
|
+
else:
|
|
212
|
+
qs = qs.filter(amount__lt=0)
|
|
258
213
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
"amount",
|
|
264
|
-
filter=Q(ref_type__in=RefTypeManager.ASSETS, amount__lt=0),
|
|
265
|
-
),
|
|
266
|
-
Value(0),
|
|
267
|
-
output_field=DecimalField(),
|
|
268
|
-
)
|
|
214
|
+
return Decimal(
|
|
215
|
+
qs.aggregate(
|
|
216
|
+
total=Coalesce(Sum("amount"), Value(0), output_field=DecimalField())
|
|
217
|
+
)["total"]
|
|
269
218
|
)
|
|
270
219
|
|
|
271
|
-
def annotate_traveling_cost(self) -> models.QuerySet:
|
|
272
|
-
return self.annotate(
|
|
273
|
-
traveling_cost=Coalesce(
|
|
274
|
-
Sum(
|
|
275
|
-
"amount",
|
|
276
|
-
filter=Q(ref_type__in=RefTypeManager.TRAVELING, amount__lt=0),
|
|
277
|
-
),
|
|
278
|
-
Value(0),
|
|
279
|
-
output_field=DecimalField(),
|
|
280
|
-
)
|
|
281
|
-
)
|
|
282
220
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
Sum(
|
|
287
|
-
"amount",
|
|
288
|
-
filter=Q(ref_type__in=RefTypeManager.PRODUCTION, amount__lt=0),
|
|
289
|
-
),
|
|
290
|
-
Value(0),
|
|
291
|
-
output_field=DecimalField(),
|
|
292
|
-
)
|
|
293
|
-
)
|
|
221
|
+
class CharWalletManager(models.Manager["CharacterWalletJournalEntryContext"]):
|
|
222
|
+
def get_queryset(self) -> CharWalletQuerySet:
|
|
223
|
+
return CharWalletQuerySet(self.model, using=self._db)
|
|
294
224
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
"amount",
|
|
300
|
-
filter=Q(ref_type__in=RefTypeManager.SKILL, amount__lt=0),
|
|
301
|
-
),
|
|
302
|
-
Value(0),
|
|
303
|
-
output_field=DecimalField(),
|
|
304
|
-
)
|
|
305
|
-
)
|
|
225
|
+
# pylint: disable=duplicate-code
|
|
226
|
+
def annotate_bounty_income(self) -> models.QuerySet:
|
|
227
|
+
"""Annotate bounty income."""
|
|
228
|
+
return self.get_queryset().annotate_bounty_income()
|
|
306
229
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
"amount",
|
|
312
|
-
filter=Q(ref_type__in=RefTypeManager.INSURANCE, amount__lt=0),
|
|
313
|
-
),
|
|
314
|
-
Value(0),
|
|
315
|
-
output_field=DecimalField(),
|
|
316
|
-
)
|
|
317
|
-
)
|
|
230
|
+
# pylint: disable=duplicate-code
|
|
231
|
+
def annotate_ess_income(self) -> models.QuerySet:
|
|
232
|
+
"""Annotate ess income."""
|
|
233
|
+
return self.get_queryset().annotate_ess_income()
|
|
318
234
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
235
|
+
# pylint: disable=duplicate-code
|
|
236
|
+
def annotate_miscellaneous(self) -> models.QuerySet:
|
|
237
|
+
"""Annotate miscellaneous income."""
|
|
238
|
+
return self.get_queryset().annotate_miscellaneous()
|
|
239
|
+
|
|
240
|
+
# pylint: disable=duplicate-code
|
|
241
|
+
def annotate_costs(self) -> models.QuerySet:
|
|
242
|
+
"""Annotate costs."""
|
|
243
|
+
return self.get_queryset().annotate_costs()
|
|
244
|
+
|
|
245
|
+
# pylint: disable=duplicate-code
|
|
246
|
+
def aggregate_bounty(self) -> dict:
|
|
247
|
+
"""Aggregate bounty income."""
|
|
248
|
+
return self.get_queryset().aggregate_bounty()
|
|
249
|
+
|
|
250
|
+
# pylint: disable=duplicate-code
|
|
251
|
+
def aggregate_ess(self) -> dict:
|
|
252
|
+
"""Aggregate ess income."""
|
|
253
|
+
return self.get_queryset().aggregate_ess()
|
|
254
|
+
|
|
255
|
+
# pylint: disable=duplicate-code
|
|
256
|
+
def aggregate_costs(self, first_party=None, second_party=None) -> dict:
|
|
257
|
+
"""Aggregate costs."""
|
|
258
|
+
return self.get_queryset().aggregate_costs(
|
|
259
|
+
first_party=first_party, second_party=second_party
|
|
329
260
|
)
|
|
330
261
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
filter=Q(ref_type__in=RefTypeManager.LP, amount__lt=0),
|
|
337
|
-
),
|
|
338
|
-
Value(0),
|
|
339
|
-
output_field=DecimalField(),
|
|
340
|
-
)
|
|
262
|
+
# pylint: disable=duplicate-code
|
|
263
|
+
def aggregate_miscellaneous(self, first_party=None, second_party=None) -> dict:
|
|
264
|
+
"""Aggregate miscellaneous income."""
|
|
265
|
+
return self.get_queryset().aggregate_miscellaneous(
|
|
266
|
+
first_party=first_party, second_party=second_party
|
|
341
267
|
)
|
|
342
268
|
|
|
269
|
+
# pylint: disable=duplicate-code
|
|
270
|
+
def aggregate_ref_type(
|
|
271
|
+
self,
|
|
272
|
+
ref_type: list,
|
|
273
|
+
first_party=None,
|
|
274
|
+
second_party=None,
|
|
275
|
+
income: bool = False,
|
|
276
|
+
) -> dict:
|
|
277
|
+
"""Aggregate income by ref_type."""
|
|
278
|
+
return self.get_queryset().aggregate_ref_type(
|
|
279
|
+
ref_type=ref_type,
|
|
280
|
+
first_party=first_party,
|
|
281
|
+
second_party=second_party,
|
|
282
|
+
income=income,
|
|
283
|
+
)
|
|
343
284
|
|
|
344
|
-
# pylint: disable=used-before-assignment
|
|
345
|
-
class CharWalletQuerySet(CharWalletCostQueryFilter):
|
|
346
285
|
@log_timing(logger)
|
|
347
286
|
def update_or_create_esi(
|
|
348
|
-
self,
|
|
287
|
+
self, owner: "CharacterOwner", force_refresh: bool = False
|
|
349
288
|
) -> "UpdateSectionResult":
|
|
350
289
|
"""Update or Create a wallet journal entry from ESI data."""
|
|
351
|
-
return
|
|
352
|
-
section=
|
|
290
|
+
return owner.update_manager.update_section_if_changed(
|
|
291
|
+
section=CharacterUpdateSection.WALLET_JOURNAL,
|
|
353
292
|
fetch_func=self._fetch_esi_data,
|
|
354
293
|
force_refresh=force_refresh,
|
|
355
294
|
)
|
|
356
295
|
|
|
357
|
-
def _fetch_esi_data(self,
|
|
296
|
+
def _fetch_esi_data(self, owner: "CharacterOwner", force_refresh: bool) -> None:
|
|
358
297
|
"""Fetch wallet journal entries from ESI data."""
|
|
359
298
|
req_scopes = ["esi-wallet.read_character_wallet.v1"]
|
|
360
|
-
token =
|
|
299
|
+
token = owner.get_token(scopes=req_scopes)
|
|
361
300
|
|
|
362
301
|
operation = esi.client.Wallet.GetCharactersCharacterIdWalletJournal(
|
|
363
|
-
character_id=
|
|
302
|
+
character_id=owner.eve_character.character_id,
|
|
364
303
|
token=token,
|
|
365
304
|
)
|
|
366
305
|
|
|
@@ -368,12 +307,12 @@ class CharWalletQuerySet(CharWalletCostQueryFilter):
|
|
|
368
307
|
force_refresh=force_refresh,
|
|
369
308
|
)
|
|
370
309
|
|
|
371
|
-
self._update_or_create_objs(character=
|
|
310
|
+
self._update_or_create_objs(character=owner, objs=journal_items)
|
|
372
311
|
|
|
373
312
|
@transaction.atomic()
|
|
374
313
|
def _update_or_create_objs(
|
|
375
314
|
self,
|
|
376
|
-
character: "
|
|
315
|
+
character: "CharacterOwner",
|
|
377
316
|
objs: list["CharactersCharacterIdWalletJournalGetItem"],
|
|
378
317
|
) -> None:
|
|
379
318
|
"""Update or Create wallet journal entries from objs data."""
|
|
@@ -421,116 +360,6 @@ class CharWalletQuerySet(CharWalletCostQueryFilter):
|
|
|
421
360
|
created_names = EveEntity.objects.create_bulk_from_esi(_new_names)
|
|
422
361
|
|
|
423
362
|
if created_names:
|
|
424
|
-
self.bulk_create(items)
|
|
363
|
+
self.bulk_create(items, batch_size=LEDGER_BULK_BATCH_SIZE)
|
|
425
364
|
else:
|
|
426
365
|
raise TokenError("ESI Fail")
|
|
427
|
-
|
|
428
|
-
def aggregate_bounty(self) -> dict:
|
|
429
|
-
"""Aggregate bounty income."""
|
|
430
|
-
return self.filter(ref_type__in=RefTypeManager.BOUNTY_PRIZES).aggregate(
|
|
431
|
-
total_bounty=Coalesce(Sum("amount"), Value(0), output_field=DecimalField())
|
|
432
|
-
)["total_bounty"]
|
|
433
|
-
|
|
434
|
-
def aggregate_ess(self) -> dict:
|
|
435
|
-
"""Aggregate ESS income."""
|
|
436
|
-
return self.filter(ref_type__in=RefTypeManager.ESS_TRANSFER).aggregate(
|
|
437
|
-
total_ess=Coalesce(Sum("amount"), Value(0), output_field=DecimalField())
|
|
438
|
-
)["total_ess"]
|
|
439
|
-
|
|
440
|
-
def aggregate_costs(self, first_party=None, second_party=None) -> dict:
|
|
441
|
-
"""Aggregate costs. first_party wird für donation exkludiert."""
|
|
442
|
-
qs = self
|
|
443
|
-
cost_types = RefTypeManager.all_ref_types()
|
|
444
|
-
donation_types = RefTypeManager.DONATION
|
|
445
|
-
|
|
446
|
-
if first_party is not None:
|
|
447
|
-
if isinstance(first_party, int):
|
|
448
|
-
first_party = [first_party]
|
|
449
|
-
qs = qs.filter(first_party__in=first_party)
|
|
450
|
-
|
|
451
|
-
if second_party is not None:
|
|
452
|
-
if isinstance(second_party, int):
|
|
453
|
-
second_party = [second_party]
|
|
454
|
-
# Exclude: alle donation mit first_party_id in Liste, Rest wie gehabt
|
|
455
|
-
qs = qs.exclude(
|
|
456
|
-
Q(ref_type__in=donation_types, first_party_id__in=second_party)
|
|
457
|
-
)
|
|
458
|
-
qs = qs.filter(Q(ref_type__in=cost_types))
|
|
459
|
-
else:
|
|
460
|
-
qs = qs.filter(Q(ref_type__in=cost_types))
|
|
461
|
-
|
|
462
|
-
qs = qs.filter(amount__lt=0)
|
|
463
|
-
return qs.aggregate(
|
|
464
|
-
total_costs=Coalesce(Sum("amount"), Value(0), output_field=DecimalField())
|
|
465
|
-
)["total_costs"]
|
|
466
|
-
|
|
467
|
-
def aggregate_miscellaneous(self, first_party=None, second_party=None) -> dict:
|
|
468
|
-
"""Aggregate miscellaneous income. first_party wird nur für donation angewandt."""
|
|
469
|
-
qs = self
|
|
470
|
-
|
|
471
|
-
misc_types = RefTypeManager.all_ref_types()
|
|
472
|
-
donation_types = RefTypeManager.DONATION
|
|
473
|
-
|
|
474
|
-
if first_party is not None:
|
|
475
|
-
if isinstance(first_party, int):
|
|
476
|
-
first_party = [first_party]
|
|
477
|
-
# Exclude: alle donation mit first_party_id in Liste, Rest wie gehabt
|
|
478
|
-
qs = qs.exclude(
|
|
479
|
-
Q(ref_type__in=donation_types, first_party_id__in=first_party)
|
|
480
|
-
)
|
|
481
|
-
qs = qs.filter(Q(ref_type__in=misc_types))
|
|
482
|
-
else:
|
|
483
|
-
qs = qs.filter(Q(ref_type__in=misc_types))
|
|
484
|
-
|
|
485
|
-
if second_party is not None:
|
|
486
|
-
if isinstance(second_party, int):
|
|
487
|
-
second_party = [second_party]
|
|
488
|
-
qs = qs.filter(second_party__in=second_party)
|
|
489
|
-
|
|
490
|
-
qs = qs.filter(amount__gt=0)
|
|
491
|
-
return qs.aggregate(
|
|
492
|
-
total_misc=Coalesce(Sum("amount"), Value(0), output_field=DecimalField())
|
|
493
|
-
)["total_misc"]
|
|
494
|
-
|
|
495
|
-
# pylint: disable=too-many-positional-arguments
|
|
496
|
-
def aggregate_ref_type(
|
|
497
|
-
self,
|
|
498
|
-
ref_type: list,
|
|
499
|
-
first_party=None,
|
|
500
|
-
second_party=None,
|
|
501
|
-
exclude=None,
|
|
502
|
-
income: bool = False,
|
|
503
|
-
) -> dict:
|
|
504
|
-
"""Aggregate income by ref_type."""
|
|
505
|
-
qs = self.filter(ref_type__in=ref_type)
|
|
506
|
-
|
|
507
|
-
if first_party is not None:
|
|
508
|
-
if isinstance(first_party, int):
|
|
509
|
-
first_party = [first_party]
|
|
510
|
-
qs = qs.filter(first_party__in=first_party)
|
|
511
|
-
|
|
512
|
-
if second_party is not None:
|
|
513
|
-
if isinstance(second_party, int):
|
|
514
|
-
second_party = [second_party]
|
|
515
|
-
qs = qs.filter(second_party__in=second_party)
|
|
516
|
-
|
|
517
|
-
if exclude is not None:
|
|
518
|
-
if isinstance(exclude, int):
|
|
519
|
-
exclude = [exclude]
|
|
520
|
-
qs = qs.exclude(first_party__in=exclude)
|
|
521
|
-
|
|
522
|
-
if income:
|
|
523
|
-
qs = qs.filter(amount__gt=0)
|
|
524
|
-
else:
|
|
525
|
-
qs = qs.filter(amount__lt=0)
|
|
526
|
-
|
|
527
|
-
return qs.aggregate(
|
|
528
|
-
total=Coalesce(Sum("amount"), Value(0), output_field=DecimalField())
|
|
529
|
-
)["total"]
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
class CharWalletManagerBase(models.Manager):
|
|
533
|
-
pass
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
CharWalletManager = CharWalletManagerBase.from_queryset(CharWalletQuerySet)
|