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
ledger/helpers/data_exporter.py
DELETED
|
@@ -1,452 +0,0 @@
|
|
|
1
|
-
# Standard Library
|
|
2
|
-
import csv
|
|
3
|
-
import gc
|
|
4
|
-
import tempfile
|
|
5
|
-
import zipfile
|
|
6
|
-
from abc import ABC, abstractmethod
|
|
7
|
-
from decimal import Decimal
|
|
8
|
-
from pathlib import Path
|
|
9
|
-
|
|
10
|
-
# Django
|
|
11
|
-
from django.conf import settings
|
|
12
|
-
from django.utils import timezone
|
|
13
|
-
|
|
14
|
-
# Alliance Auth
|
|
15
|
-
from allianceauth.eveonline.models import EveAllianceInfo
|
|
16
|
-
from allianceauth.services.hooks import get_extension_logger
|
|
17
|
-
|
|
18
|
-
# Alliance Auth (External Libs)
|
|
19
|
-
from app_utils.logging import LoggerAddTag
|
|
20
|
-
|
|
21
|
-
# AA Ledger
|
|
22
|
-
from ledger import __title__
|
|
23
|
-
from ledger.helpers.alliance import AllianceData
|
|
24
|
-
from ledger.helpers.corporation import CorporationData
|
|
25
|
-
from ledger.models.corporationaudit import (
|
|
26
|
-
CorporationAudit,
|
|
27
|
-
CorporationWalletJournalEntry,
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
logger = LoggerAddTag(get_extension_logger(__name__), __title__)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
def int_or_none(val) -> int | None:
|
|
34
|
-
"""Convert value to int or return None."""
|
|
35
|
-
if val is None or val == "":
|
|
36
|
-
return None
|
|
37
|
-
try:
|
|
38
|
-
return int(val)
|
|
39
|
-
except (ValueError, TypeError):
|
|
40
|
-
return None
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
def file_to_zip(source_file: Path, destination: Path) -> Path:
|
|
44
|
-
"""Create a zip archive from a file."""
|
|
45
|
-
destination.mkdir(parents=True, exist_ok=True)
|
|
46
|
-
zip_file = (destination / source_file.name).with_suffix(".zip")
|
|
47
|
-
with zipfile.ZipFile(
|
|
48
|
-
file=zip_file, mode="w", compression=zipfile.ZIP_DEFLATED
|
|
49
|
-
) as my_zip:
|
|
50
|
-
my_zip.write(filename=source_file, arcname=source_file.name)
|
|
51
|
-
logger.info("Created export file: %s", zip_file)
|
|
52
|
-
return zip_file
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
def default_destination() -> Path:
|
|
56
|
-
"""Return default destination path."""
|
|
57
|
-
return (
|
|
58
|
-
Path(settings.BASE_DIR) / str(CorporationAudit._meta.app_label) / "data_exports"
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
def export_ledger_to_archive(
|
|
63
|
-
ledger_type: str, entity_id: int, division_id: int, year: int, month: int
|
|
64
|
-
) -> str:
|
|
65
|
-
"""Export data for given ledger into a zipped file in destination."""
|
|
66
|
-
exporter = LedgerCSVExporter.create_exporter(
|
|
67
|
-
ledger_type, entity_id, division_id, year, month
|
|
68
|
-
)
|
|
69
|
-
try:
|
|
70
|
-
with tempfile.TemporaryDirectory() as temp_dirname:
|
|
71
|
-
csv_file = exporter.write_to_file(temp_dirname)
|
|
72
|
-
destination = default_destination()
|
|
73
|
-
zip_file_path = file_to_zip(csv_file, destination)
|
|
74
|
-
except ValueError as ve:
|
|
75
|
-
logger.debug("Error exporting ledger to archive: %s", ve)
|
|
76
|
-
return f"{ve}"
|
|
77
|
-
gc.collect()
|
|
78
|
-
return str(zip_file_path)
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
class LedgerCSVExporter(ABC):
|
|
82
|
-
"""CSV exporter for ledger data."""
|
|
83
|
-
|
|
84
|
-
def __init__(self):
|
|
85
|
-
# _now is available for subclasses if needed
|
|
86
|
-
self._now = timezone.now()
|
|
87
|
-
if not hasattr(self, "topic"):
|
|
88
|
-
raise NotImplementedError("Subclasses must define 'topic' attribute")
|
|
89
|
-
|
|
90
|
-
@property
|
|
91
|
-
def output_basename(self) -> Path:
|
|
92
|
-
"""Return the base name for the output file."""
|
|
93
|
-
app_label = str(CorporationAudit._meta.app_label)
|
|
94
|
-
# Try to discover an entity id from known attributes set by exporters
|
|
95
|
-
entity_id = (
|
|
96
|
-
getattr(self, "corporation_id", None)
|
|
97
|
-
or getattr(self, "alliance_id", None)
|
|
98
|
-
or ""
|
|
99
|
-
)
|
|
100
|
-
division_id = getattr(self, "division_id", None) or ""
|
|
101
|
-
year = getattr(self, "year", "") or ""
|
|
102
|
-
month = getattr(self, "month", "") or ""
|
|
103
|
-
|
|
104
|
-
export_key = self.encoder(entity_id, division_id, year, month)
|
|
105
|
-
if not export_key:
|
|
106
|
-
raise ValueError("Could not create export key for output basename")
|
|
107
|
-
# pylint: disable=no-member
|
|
108
|
-
return Path(f"{app_label}_{self.topic}_{export_key}")
|
|
109
|
-
|
|
110
|
-
@staticmethod
|
|
111
|
-
def encoder(
|
|
112
|
-
entity_id: int, division_id: int = None, year: int = None, month: int = None
|
|
113
|
-
) -> str | None:
|
|
114
|
-
"""Create a compact export key: "<entity_id>:<division_id>:<year>:<month>" encoded as hex"""
|
|
115
|
-
try:
|
|
116
|
-
parts = [
|
|
117
|
-
"" if v is None else str(v)
|
|
118
|
-
for v in (entity_id, division_id, year, month)
|
|
119
|
-
]
|
|
120
|
-
key = ":".join(parts)
|
|
121
|
-
return key.encode("utf-8").hex()
|
|
122
|
-
# pylint: disable=broad-except
|
|
123
|
-
except Exception:
|
|
124
|
-
return None
|
|
125
|
-
|
|
126
|
-
@staticmethod
|
|
127
|
-
def decoder(key: str) -> tuple[int | None, int | None, int | None, int | None]:
|
|
128
|
-
"""Decode a compact export key from hex to (entity_id, division_id, year, month).
|
|
129
|
-
|
|
130
|
-
Returns ints when values are numeric, otherwise None for missing/empty values.
|
|
131
|
-
"""
|
|
132
|
-
try:
|
|
133
|
-
packed = bytes.fromhex(key).decode("utf-8")
|
|
134
|
-
key_parts = packed.split(":")
|
|
135
|
-
|
|
136
|
-
entity_id = int_or_none(key_parts[0]) if len(key_parts) > 0 else None
|
|
137
|
-
division_id = int_or_none(key_parts[1]) if len(key_parts) > 1 else None
|
|
138
|
-
year = int_or_none(key_parts[2]) if len(key_parts) > 2 else None
|
|
139
|
-
month = int_or_none(key_parts[3]) if len(key_parts) > 3 else None
|
|
140
|
-
return entity_id, division_id, year, month
|
|
141
|
-
# pylint: disable=broad-except
|
|
142
|
-
except Exception:
|
|
143
|
-
return None, None, None, None
|
|
144
|
-
|
|
145
|
-
@abstractmethod
|
|
146
|
-
def create_data_export(self) -> list[dict]:
|
|
147
|
-
"""Generate data export."""
|
|
148
|
-
raise NotImplementedError()
|
|
149
|
-
|
|
150
|
-
@property
|
|
151
|
-
@abstractmethod
|
|
152
|
-
def has_data(self) -> bool:
|
|
153
|
-
"""Check if there is data to export."""
|
|
154
|
-
raise NotImplementedError()
|
|
155
|
-
|
|
156
|
-
def output_path(self, destination: str) -> Path:
|
|
157
|
-
"""Return output path for this export."""
|
|
158
|
-
return Path(destination) / self.output_basename.with_suffix(".csv")
|
|
159
|
-
|
|
160
|
-
def _extract_entity_info(self, item: dict) -> dict:
|
|
161
|
-
"""Extract entity information from the data item."""
|
|
162
|
-
entity = item.get("entity")
|
|
163
|
-
if not entity:
|
|
164
|
-
return {"entity_id": "", "entity_name": "", "entity_type": ""}
|
|
165
|
-
|
|
166
|
-
return {
|
|
167
|
-
"entity_id": getattr(entity, "entity_id", ""),
|
|
168
|
-
"entity_name": getattr(entity, "entity_name", ""),
|
|
169
|
-
"entity_type": getattr(entity, "type", ""),
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
def _clean_decimal_value(self, value) -> str:
|
|
173
|
-
"""Clean decimal values from the Decimal() wrapper."""
|
|
174
|
-
if (
|
|
175
|
-
isinstance(value, str)
|
|
176
|
-
and value.startswith('Decimal("')
|
|
177
|
-
and value.endswith('")')
|
|
178
|
-
):
|
|
179
|
-
# Extract the value from Decimal("value") format
|
|
180
|
-
return value[9:-2] # Remove 'Decimal("' and '")')
|
|
181
|
-
if isinstance(value, Decimal):
|
|
182
|
-
return str(value)
|
|
183
|
-
return str(value) if value is not None else "0"
|
|
184
|
-
|
|
185
|
-
def _extract_ledger_data(self, item: dict) -> dict:
|
|
186
|
-
"""Extract ledger financial data from the item."""
|
|
187
|
-
ledger = item.get("ledger", {})
|
|
188
|
-
|
|
189
|
-
return {
|
|
190
|
-
"bounty": self._clean_decimal_value(ledger.get("bounty", "0")),
|
|
191
|
-
"ess": self._clean_decimal_value(ledger.get("ess", "0")),
|
|
192
|
-
"miscellaneous": self._clean_decimal_value(
|
|
193
|
-
ledger.get("miscellaneous", "0")
|
|
194
|
-
),
|
|
195
|
-
"costs": self._clean_decimal_value(ledger.get("costs", "0")),
|
|
196
|
-
"total": self._clean_decimal_value(ledger.get("total", "0")),
|
|
197
|
-
"mining": self._clean_decimal_value(
|
|
198
|
-
ledger.get("mining", "0")
|
|
199
|
-
), # Include mining if present
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
def write_to_file(self, destination: Path) -> Path:
|
|
203
|
-
"""Write ledger data to CSV file."""
|
|
204
|
-
output_file = self.output_path(destination)
|
|
205
|
-
|
|
206
|
-
# Define CSV headers
|
|
207
|
-
headers = [
|
|
208
|
-
"entity_id",
|
|
209
|
-
"entity_name",
|
|
210
|
-
"entity_type",
|
|
211
|
-
"bounty",
|
|
212
|
-
"ess",
|
|
213
|
-
"miscellaneous",
|
|
214
|
-
"costs",
|
|
215
|
-
"mining",
|
|
216
|
-
"total",
|
|
217
|
-
]
|
|
218
|
-
|
|
219
|
-
if self.has_data is False:
|
|
220
|
-
raise ValueError("No data to export")
|
|
221
|
-
|
|
222
|
-
with output_file.open("w", newline="", encoding="utf-8") as csv_file:
|
|
223
|
-
writer = csv.DictWriter(csv_file, fieldnames=headers)
|
|
224
|
-
writer.writeheader()
|
|
225
|
-
|
|
226
|
-
for item in self.create_data_export():
|
|
227
|
-
if not item: # Skip empty items
|
|
228
|
-
continue
|
|
229
|
-
|
|
230
|
-
# Extract entity and ledger information
|
|
231
|
-
entity_info = self._extract_entity_info(item)
|
|
232
|
-
ledger_data = self._extract_ledger_data(item)
|
|
233
|
-
|
|
234
|
-
# Combine all data into a single row
|
|
235
|
-
row_data = {**entity_info, **ledger_data}
|
|
236
|
-
|
|
237
|
-
writer.writerow(row_data)
|
|
238
|
-
logger.info(
|
|
239
|
-
f"Exported {len(self.create_data_export())} ledger entries to {output_file}"
|
|
240
|
-
)
|
|
241
|
-
return output_file
|
|
242
|
-
|
|
243
|
-
@classmethod
|
|
244
|
-
# pylint: disable=too-many-positional-arguments
|
|
245
|
-
def create_exporter(
|
|
246
|
-
cls,
|
|
247
|
-
ledger_type: str,
|
|
248
|
-
entity_id: int,
|
|
249
|
-
division_id: int = None,
|
|
250
|
-
year: int = None,
|
|
251
|
-
month: int = None,
|
|
252
|
-
):
|
|
253
|
-
"""Create a LedgerCSVExporter instance."""
|
|
254
|
-
if ledger_type == "corporation":
|
|
255
|
-
if entity_id is None:
|
|
256
|
-
raise ValueError("corporation_id must be provided")
|
|
257
|
-
return CorporationExporter(
|
|
258
|
-
entity_id=entity_id, division_id=division_id, year=year, month=month
|
|
259
|
-
)
|
|
260
|
-
|
|
261
|
-
if ledger_type == "alliance":
|
|
262
|
-
if entity_id is None:
|
|
263
|
-
raise ValueError("alliance_id must be provided")
|
|
264
|
-
return AllianceExporter(entity_id=entity_id, year=year, month=month)
|
|
265
|
-
|
|
266
|
-
raise ValueError("Invalid ledger_type")
|
|
267
|
-
|
|
268
|
-
def gather_export_files(self) -> list[dict]:
|
|
269
|
-
"""Gather export files in the destination folder and parse metadata from filenames.
|
|
270
|
-
Expected filename format (without suffix):
|
|
271
|
-
<app_label>_<topic>_<export_key_hex>
|
|
272
|
-
|
|
273
|
-
The export_key_hex is a hex encoding of the UTF-8 string
|
|
274
|
-
"<entity_id>:<division_id>:<year>:<month>"
|
|
275
|
-
Only files matching this new format are considered.
|
|
276
|
-
|
|
277
|
-
This is an instance method and will filter files for the exporter instance
|
|
278
|
-
by using the instance's corporation_id or alliance_id attribute.
|
|
279
|
-
"""
|
|
280
|
-
# Determine the entity id for this exporter instance. Exporter subclasses
|
|
281
|
-
instance_entity_id = getattr(self, "corporation_id", None) or getattr(
|
|
282
|
-
self, "alliance_id", None
|
|
283
|
-
)
|
|
284
|
-
if instance_entity_id is None:
|
|
285
|
-
raise ValueError(
|
|
286
|
-
"Exporter instance must have 'corporation_id' or 'alliance_id' to gather files"
|
|
287
|
-
)
|
|
288
|
-
|
|
289
|
-
destination_folder = default_destination()
|
|
290
|
-
results: list[dict] = []
|
|
291
|
-
|
|
292
|
-
# If destination folder doesn't exist, return empty
|
|
293
|
-
if not destination_folder.exists():
|
|
294
|
-
return results
|
|
295
|
-
|
|
296
|
-
existing_files = list(
|
|
297
|
-
destination_folder.glob(f"{str(CorporationAudit._meta.app_label)}_*.zip")
|
|
298
|
-
)
|
|
299
|
-
|
|
300
|
-
if not existing_files:
|
|
301
|
-
return results
|
|
302
|
-
|
|
303
|
-
for file in existing_files:
|
|
304
|
-
name = file.with_suffix("").name
|
|
305
|
-
parts = name.split("_")
|
|
306
|
-
topic = parts[1] if len(parts) > 1 else ""
|
|
307
|
-
|
|
308
|
-
# Only attempt to parse the export hex key (third segment).
|
|
309
|
-
if len(parts) <= 2:
|
|
310
|
-
continue
|
|
311
|
-
|
|
312
|
-
key = parts[2]
|
|
313
|
-
entity_id, division_id, year, month = LedgerCSVExporter.decoder(key)
|
|
314
|
-
|
|
315
|
-
# Only include files matching the requested entity id and topic
|
|
316
|
-
if entity_id is None or entity_id != instance_entity_id:
|
|
317
|
-
continue
|
|
318
|
-
|
|
319
|
-
# Also filter by exporter topic so we don't mix corporation/alliance exports
|
|
320
|
-
if topic != getattr(self, "topic", ""):
|
|
321
|
-
continue
|
|
322
|
-
|
|
323
|
-
try:
|
|
324
|
-
last_updated = timezone.datetime.fromtimestamp(
|
|
325
|
-
file.stat().st_mtime, tz=timezone.utc
|
|
326
|
-
)
|
|
327
|
-
# pylint: disable=broad-except
|
|
328
|
-
except Exception:
|
|
329
|
-
logger.debug("Could not get last modified time for file %s", file)
|
|
330
|
-
last_updated = None
|
|
331
|
-
|
|
332
|
-
results.append(
|
|
333
|
-
{
|
|
334
|
-
"topic": topic,
|
|
335
|
-
"entity_id": entity_id,
|
|
336
|
-
"division_id": (
|
|
337
|
-
division_id if division_id is not None else "All Divisions"
|
|
338
|
-
),
|
|
339
|
-
"year": year,
|
|
340
|
-
"month": month if month is not None else "All Months",
|
|
341
|
-
"last_updated": last_updated,
|
|
342
|
-
"hash": key,
|
|
343
|
-
}
|
|
344
|
-
)
|
|
345
|
-
|
|
346
|
-
return results
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
class CorporationExporter(LedgerCSVExporter):
|
|
350
|
-
"""CSV Exporter for Corporation Ledger Data."""
|
|
351
|
-
|
|
352
|
-
topic = "corporation-ledger"
|
|
353
|
-
|
|
354
|
-
def __init__(
|
|
355
|
-
self,
|
|
356
|
-
entity_id: int,
|
|
357
|
-
division_id: int = None,
|
|
358
|
-
year: int = None,
|
|
359
|
-
month: int = None,
|
|
360
|
-
):
|
|
361
|
-
super().__init__()
|
|
362
|
-
self.corporation_id = entity_id
|
|
363
|
-
self.division_id = division_id
|
|
364
|
-
self.year = year
|
|
365
|
-
self.month = month
|
|
366
|
-
|
|
367
|
-
@property
|
|
368
|
-
def has_data(self) -> bool:
|
|
369
|
-
"""Check if there is data to export."""
|
|
370
|
-
return CorporationWalletJournalEntry.objects.filter(
|
|
371
|
-
division__corporation__corporation__corporation_id=self.corporation_id
|
|
372
|
-
).exists()
|
|
373
|
-
|
|
374
|
-
def create_data_export(
|
|
375
|
-
self,
|
|
376
|
-
corporation_id: int = None,
|
|
377
|
-
division_id: int = None,
|
|
378
|
-
year: int = None,
|
|
379
|
-
month: int = None,
|
|
380
|
-
) -> list[dict]:
|
|
381
|
-
"""Generate data export for corporation ledger."""
|
|
382
|
-
report_corporation_id = (
|
|
383
|
-
corporation_id if corporation_id is not None else self.corporation_id
|
|
384
|
-
)
|
|
385
|
-
report_division_id = (
|
|
386
|
-
division_id if division_id is not None else self.division_id
|
|
387
|
-
)
|
|
388
|
-
report_year = year if year is not None else self.year
|
|
389
|
-
report_month = month if month is not None else self.month
|
|
390
|
-
|
|
391
|
-
try:
|
|
392
|
-
corporation = CorporationAudit.objects.get(
|
|
393
|
-
corporation__corporation_id=report_corporation_id
|
|
394
|
-
)
|
|
395
|
-
# Create CorporationData inside the task
|
|
396
|
-
ledger_data = CorporationData(
|
|
397
|
-
corporation=corporation,
|
|
398
|
-
division_id=report_division_id,
|
|
399
|
-
year=report_year,
|
|
400
|
-
month=report_month,
|
|
401
|
-
)
|
|
402
|
-
return ledger_data.generate_data_export()
|
|
403
|
-
except CorporationAudit.DoesNotExist as exc:
|
|
404
|
-
raise ValueError("Corporation not found") from exc
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
class AllianceExporter(LedgerCSVExporter):
|
|
408
|
-
"""CSV Exporter for Alliance Ledger Data."""
|
|
409
|
-
|
|
410
|
-
topic = "alliance-ledger"
|
|
411
|
-
|
|
412
|
-
def __init__(self, entity_id: int, year: int = None, month: int = None):
|
|
413
|
-
super().__init__()
|
|
414
|
-
self.alliance_id = entity_id
|
|
415
|
-
self.year = year
|
|
416
|
-
self.month = month
|
|
417
|
-
|
|
418
|
-
@property
|
|
419
|
-
def has_data(self) -> bool:
|
|
420
|
-
"""Check if there is data to export."""
|
|
421
|
-
corporations = CorporationAudit.objects.filter(
|
|
422
|
-
corporation__alliance__alliance_id=self.alliance_id
|
|
423
|
-
).values_list("corporation__corporation_id", flat=True)
|
|
424
|
-
|
|
425
|
-
if not corporations:
|
|
426
|
-
return False
|
|
427
|
-
|
|
428
|
-
return CorporationWalletJournalEntry.objects.filter(
|
|
429
|
-
division__corporation__corporation__corporation_id__in=corporations
|
|
430
|
-
).exists()
|
|
431
|
-
|
|
432
|
-
def create_data_export(
|
|
433
|
-
self, alliance_id: int = None, year: int = None, month: int = None
|
|
434
|
-
) -> list[dict]:
|
|
435
|
-
"""Generate data export for alliance ledger."""
|
|
436
|
-
report_alliance_id = (
|
|
437
|
-
alliance_id if alliance_id is not None else self.alliance_id
|
|
438
|
-
)
|
|
439
|
-
report_year = year if year is not None else self.year
|
|
440
|
-
report_month = month if month is not None else self.month
|
|
441
|
-
|
|
442
|
-
try:
|
|
443
|
-
alliance = EveAllianceInfo.objects.get(alliance_id=report_alliance_id)
|
|
444
|
-
ledger_data = AllianceData(
|
|
445
|
-
alliance=alliance,
|
|
446
|
-
year=report_year,
|
|
447
|
-
month=report_month,
|
|
448
|
-
request=None,
|
|
449
|
-
)
|
|
450
|
-
return ledger_data.generate_data_export()
|
|
451
|
-
except EveAllianceInfo.DoesNotExist as exc:
|
|
452
|
-
raise ValueError("Alliance not found") from exc
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
$(document).ready(() => {
|
|
2
|
-
/* global PlanetaryTable */
|
|
3
|
-
const modalRequestApprove = $('#ledger-planetary-confirm');
|
|
4
|
-
const modalErrorMessage = $('#modal-error-message');
|
|
5
|
-
|
|
6
|
-
// Approve Request Modal
|
|
7
|
-
modalRequestApprove.on('show.bs.modal', (event) => {
|
|
8
|
-
const button = $(event.relatedTarget);
|
|
9
|
-
const url = button.data('action');
|
|
10
|
-
|
|
11
|
-
// Extract the title from the button
|
|
12
|
-
const modalTitle = button.data('title');
|
|
13
|
-
const modalTitleDiv = modalRequestApprove.find('#modal-title');
|
|
14
|
-
modalTitleDiv.html(modalTitle);
|
|
15
|
-
|
|
16
|
-
// Extract the text from the button
|
|
17
|
-
const modalText = button.data('text');
|
|
18
|
-
const modalDiv = modalRequestApprove.find('#modal-request-text');
|
|
19
|
-
modalDiv.html(modalText);
|
|
20
|
-
|
|
21
|
-
// Set the character_id in the hidden input field
|
|
22
|
-
const characterId = button.data('character-id');
|
|
23
|
-
modalRequestApprove.find('input[name="character_id"]').val(characterId);
|
|
24
|
-
|
|
25
|
-
// Set the planet_id in the hidden input field
|
|
26
|
-
const planetId = button.data('planet-id');
|
|
27
|
-
modalRequestApprove.find('input[name="planet_id"]').val(planetId);
|
|
28
|
-
|
|
29
|
-
$('#modal-button-confirm-confirm-request').on('click', () => {
|
|
30
|
-
const form = modalRequestApprove.find('form');
|
|
31
|
-
const csrfMiddlewareToken = form.find('input[name="csrfmiddlewaretoken"]').val();
|
|
32
|
-
|
|
33
|
-
// Remove any existing error messages
|
|
34
|
-
form.find('.alert-danger').remove();
|
|
35
|
-
|
|
36
|
-
const posting = $.post(
|
|
37
|
-
url,
|
|
38
|
-
{
|
|
39
|
-
character_id: characterId,
|
|
40
|
-
planet_id: planetId,
|
|
41
|
-
csrfmiddlewaretoken: csrfMiddlewareToken
|
|
42
|
-
}
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
posting.done(() => {
|
|
46
|
-
modalRequestApprove.modal('hide');
|
|
47
|
-
PlanetaryTable.ajax.reload(); // Reload the DataTable
|
|
48
|
-
|
|
49
|
-
}).fail((xhr, _, __) => {
|
|
50
|
-
const response = JSON.parse(xhr.responseText);
|
|
51
|
-
modalErrorMessage.text(response.message).removeClass('d-none'); // Show the error message
|
|
52
|
-
modalErrorMessage.addClass('l-shake'); // Add the shake class
|
|
53
|
-
|
|
54
|
-
// Remove the shake class after 2 seconds
|
|
55
|
-
setTimeout(() => {
|
|
56
|
-
modalErrorMessage.removeClass('l-shake');
|
|
57
|
-
}, 2000);
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
}).on('hide.bs.modal', () => {
|
|
61
|
-
modalRequestApprove.find('.alert-danger').remove();
|
|
62
|
-
$('#modal-button-confirm-confirm-request').unbind('click');
|
|
63
|
-
modalErrorMessage.addClass('d-none');
|
|
64
|
-
modalErrorMessage.val('');
|
|
65
|
-
});
|
|
66
|
-
});
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
/* global planetarySettings, bootstrap */
|
|
2
|
-
|
|
3
|
-
$(document).ready(() => {
|
|
4
|
-
var switchAlarmText = planetarySettings.switchAlarmText;
|
|
5
|
-
var switchAlarm = planetarySettings.switchAlarm;
|
|
6
|
-
var alarmActivated = planetarySettings.alarmActivated;
|
|
7
|
-
var alarmDeactivated = planetarySettings.alarmDeactivated;
|
|
8
|
-
var viewSwitchAlarmUrl = planetarySettings.viewSwitchAlarmUrl;
|
|
9
|
-
|
|
10
|
-
function viewFactoryUrl(characterId, planetId) {
|
|
11
|
-
return planetarySettings.viewFactoryUrl.replace('1337', characterId).replace('1337', planetId);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function viewExtractorUrl(characterId, planetId) {
|
|
15
|
-
return planetarySettings.viewExtractorUrl.replace('1337', characterId).replace('1337', planetId);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
// Initialize DataTable
|
|
21
|
-
const PlanetaryTable = $('#planets-details').DataTable({
|
|
22
|
-
ajax: {
|
|
23
|
-
url: planetarySettings.planetaryUrl,
|
|
24
|
-
dataSrc: '',
|
|
25
|
-
cache: false
|
|
26
|
-
},
|
|
27
|
-
columns: [
|
|
28
|
-
{
|
|
29
|
-
data: 'character_name',
|
|
30
|
-
render: function(data, type, row) {
|
|
31
|
-
return `
|
|
32
|
-
<img src="https://images.evetech.net/characters/${row.character_id}/portrait?size=32" class="rounded-circle" style="margin-right: 5px;">
|
|
33
|
-
${data}
|
|
34
|
-
`;
|
|
35
|
-
}
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
data: 'planet',
|
|
39
|
-
render: function(data, type, row) {
|
|
40
|
-
return `
|
|
41
|
-
<img src="https://images.evetech.net/types/${row.planet_type_id}/icon?size=32" class="rounded-circle" style="margin-right: 5px;" data-tooltip-toggle="ledger" title="${row.planet}">
|
|
42
|
-
${data}
|
|
43
|
-
<i class="fa-solid fa-bullhorn" style="margin-left: 5px; color: ${row.alarm ? 'green' : 'red'};" title="${row.alarm ? alarmActivated : alarmDeactivated}" data-tooltip-toggle="ledger"></i>
|
|
44
|
-
`;
|
|
45
|
-
}
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
data: 'upgrade_level'
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
data: 'products',
|
|
52
|
-
render: function(data, type, row) {
|
|
53
|
-
return Object.values(data.processed).map(product => `
|
|
54
|
-
<img src="https://images.evetech.net/types/${product.id}/icon?size=32" data-tooltip-toggle="ledger" title="${product.name}">
|
|
55
|
-
`).join(' ') + `
|
|
56
|
-
<button class="btn btn-primary btn-sm btn-square"
|
|
57
|
-
data-bs-toggle="modal"
|
|
58
|
-
data-bs-target="#modalViewFactoryContainer"
|
|
59
|
-
data-ajax_factory="${viewFactoryUrl(row.character_id, row.planet_id)}"
|
|
60
|
-
data-tooltip-toggle="ledger"
|
|
61
|
-
data-bs-placement="left"
|
|
62
|
-
title="${row.character_name} - ${row.planet}"
|
|
63
|
-
>
|
|
64
|
-
<span class="fas fa-info"></span>
|
|
65
|
-
</button>`;
|
|
66
|
-
}
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
data: 'percentage'
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
data: 'extractors',
|
|
73
|
-
render: function(data, type, row) {
|
|
74
|
-
return Object.values(row.products.raw).map(product => `
|
|
75
|
-
<img src="https://images.evetech.net/types/${product.id}/icon?size=32" data-tooltip-toggle="ledger" title="${product.name}">
|
|
76
|
-
`).join(' ') + `
|
|
77
|
-
<button class="btn btn-primary btn-sm btn-square"
|
|
78
|
-
data-bs-toggle="modal"
|
|
79
|
-
data-bs-target="#modalViewExtractorContainer"
|
|
80
|
-
data-ajax_extractor="${viewExtractorUrl(row.character_id, row.planet_id)}"
|
|
81
|
-
data-tooltip-toggle="ledger"
|
|
82
|
-
data-bs-placement="left"
|
|
83
|
-
title="${row.character_name} - ${row.planet}"
|
|
84
|
-
>
|
|
85
|
-
<span class="fas fa-info"></span>
|
|
86
|
-
</button>`;
|
|
87
|
-
}
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
data: 'status',
|
|
91
|
-
render: function(data, type, row) {
|
|
92
|
-
return `
|
|
93
|
-
<img src="/static/ledger/images/${row.expired ? 'red' : 'green'}.png" style="width: 24px; height: 24px;" title="${row.expired ? 'Expired' : 'Active'}" data-tooltip-toggle="ledger">
|
|
94
|
-
`;
|
|
95
|
-
}
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
data: 'last_update',
|
|
99
|
-
render: function(data, type, row) {
|
|
100
|
-
if (data === null) {
|
|
101
|
-
return `<span class="text-warning" data-tooltip-toggle="ledger">Not updated yet</span>`;
|
|
102
|
-
}
|
|
103
|
-
return new Date(data).toLocaleString();
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
data: 'actions',
|
|
109
|
-
render: function(data, type, row) {
|
|
110
|
-
return `
|
|
111
|
-
<button type="button" class="btn btn-primary btn-sm btn-square me-2" data-bs-toggle="modal" data-tooltip-toggle="ledger" data-character-id="${row.character_id}" data-planet-id="${row.planet_id}" data-title="${switchAlarm}" data-text="${switchAlarmText} \n${row.character_name} - ${row.planet}?" data-bs-target="#ledger-planetary-confirm" data-action="${viewSwitchAlarmUrl}" aria-label="Toggle Alarm">
|
|
112
|
-
<span class="fas fa-bullhorn"></span>
|
|
113
|
-
</button>
|
|
114
|
-
`;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
],
|
|
118
|
-
columnDefs: [
|
|
119
|
-
{
|
|
120
|
-
orderable: false,
|
|
121
|
-
targets: 'no-sort',
|
|
122
|
-
}
|
|
123
|
-
],
|
|
124
|
-
order: [
|
|
125
|
-
[4, 'desc']
|
|
126
|
-
],
|
|
127
|
-
pageLength: 25,
|
|
128
|
-
initComplete: function() {
|
|
129
|
-
$('[data-tooltip-toggle="ledger"]').tooltip({
|
|
130
|
-
trigger: 'hover',
|
|
131
|
-
});
|
|
132
|
-
$('#ledger-index').addClass('show');
|
|
133
|
-
},
|
|
134
|
-
drawCallback: function() {
|
|
135
|
-
$('[data-tooltip-toggle="ledger"]').tooltip({
|
|
136
|
-
trigger: 'hover',
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
// Make PlanetaryTable globally accessible
|
|
142
|
-
window.PlanetaryTable = PlanetaryTable;
|
|
143
|
-
});
|