aa-ledger 0.9.8__py3-none-any.whl → 0.9.9.1__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-0.9.8.dist-info → aa_ledger-0.9.9.1.dist-info}/METADATA +3 -1
- {aa_ledger-0.9.8.dist-info → aa_ledger-0.9.9.1.dist-info}/RECORD +78 -76
- ledger/__init__.py +9 -9
- ledger/api/api_helper/billboard_helper.py +55 -26
- ledger/api/ledger/admin.py +1 -1
- ledger/app_settings.py +18 -11
- ledger/constants.py +5 -0
- ledger/decorators.py +92 -11
- ledger/helpers/alliance.py +119 -91
- ledger/helpers/character.py +260 -252
- ledger/helpers/core.py +565 -565
- ledger/helpers/corporation.py +237 -187
- ledger/helpers/etag.py +2 -1
- ledger/helpers/ref_type.py +475 -475
- ledger/locale/cs_CZ/LC_MESSAGES/django.po +942 -932
- ledger/locale/de/LC_MESSAGES/django.mo +0 -0
- ledger/locale/de/LC_MESSAGES/django.po +961 -945
- ledger/locale/django.pot +942 -932
- ledger/locale/es/LC_MESSAGES/django.po +943 -933
- ledger/locale/fr_FR/LC_MESSAGES/django.po +942 -932
- ledger/locale/it_IT/LC_MESSAGES/django.po +942 -932
- ledger/locale/ja/LC_MESSAGES/django.po +943 -933
- ledger/locale/ko_KR/LC_MESSAGES/django.po +942 -932
- ledger/locale/nl_NL/LC_MESSAGES/django.po +942 -932
- ledger/locale/pl_PL/LC_MESSAGES/django.po +942 -932
- ledger/locale/ru/LC_MESSAGES/django.po +945 -935
- ledger/locale/sk/LC_MESSAGES/django.po +944 -934
- ledger/locale/uk/LC_MESSAGES/django.po +946 -936
- ledger/locale/zh_Hans/LC_MESSAGES/django.po +943 -933
- ledger/managers/character_mining_manager.py +66 -19
- ledger/managers/character_planetary_manager.py +1 -1
- ledger/migrations/0016_characterminingledger_price_per_unit.py +21 -0
- ledger/models/characteraudit.py +32 -1
- ledger/static/ledger/css/cards.css +1 -1
- ledger/static/ledger/css/table.css +1 -1
- ledger/static/ledger/js/charts.js +7 -227
- ledger/static/ledger/js/planetary.js +1 -0
- ledger/tasks.py +1 -8
- ledger/templates/ledger/allyledger/admin/alliance_administration.html +17 -8
- ledger/templates/ledger/allyledger/admin/alliance_overview.html +75 -89
- ledger/templates/ledger/allyledger/alliance_ledger.html +8 -10
- ledger/templates/ledger/bundles/ally-administration-bundles.html +2 -0
- ledger/templates/ledger/bundles/char-administration-bundles.html +2 -0
- ledger/templates/ledger/bundles/character-ledger-bundles.html +66 -64
- ledger/templates/ledger/bundles/corp-administration-bundles.html +2 -0
- ledger/templates/ledger/bundles/corporation-ledger-bundles.html +75 -73
- ledger/templates/ledger/charledger/admin/character_administration.html +10 -8
- ledger/templates/ledger/charledger/admin/character_overview.html +69 -86
- ledger/templates/ledger/charledger/character_ledger.html +11 -15
- ledger/templates/ledger/charledger/planetary/planetary_ledger.html +2 -6
- ledger/templates/ledger/corpledger/admin/corporation_administration.html +10 -8
- ledger/templates/ledger/corpledger/admin/corporation_overview.html +71 -83
- ledger/templates/ledger/corpledger/corporation_ledger.html +55 -14
- ledger/templates/ledger/partials/administration/alliance.html +28 -49
- ledger/templates/ledger/partials/administration/alliance_corporations.html +58 -0
- ledger/templates/ledger/partials/administration/corporation_characters.html +26 -28
- ledger/templates/ledger/partials/information/daily.html +1 -1
- ledger/templates/ledger/partials/information/day.html +1 -7
- ledger/templates/ledger/partials/information/hourly.html +1 -7
- ledger/templates/ledger/partials/information/summary.html +88 -84
- ledger/templates/ledger/partials/information/view_character_content.html +35 -35
- ledger/templates/ledger/partials/table/char-ledger.html +14 -5
- ledger/templates/ledger/partials/table/corp-ledger.html +3 -3
- ledger/templates/ledger/partials/view/card.html +2 -2
- ledger/tests/test_decarators.py +102 -17
- ledger/tests/test_helpers/test_etag.py +7 -6
- ledger/tests/test_managers/test_character_mining_manager.py +2 -1
- ledger/tests/test_models/test_characterminingledger.py +38 -2
- ledger/tests/test_tasks.py +4 -4
- ledger/tests/test_templatetags.py +5 -2
- ledger/tests/test_views/test_access.py +852 -852
- ledger/tests/testdata/esi.json +1 -2
- ledger/tests/testdata/eveuniverse.json +90 -48
- ledger/urls.py +66 -21
- ledger/views/alliance/alliance_ledger.py +4 -3
- ledger/views/corporation/corporation_ledger.py +25 -9
- {aa_ledger-0.9.8.dist-info → aa_ledger-0.9.9.1.dist-info}/WHEEL +0 -0
- {aa_ledger-0.9.8.dist-info → aa_ledger-0.9.9.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -4,7 +4,14 @@ from typing import TYPE_CHECKING
|
|
|
4
4
|
|
|
5
5
|
# Django
|
|
6
6
|
from django.db import models, transaction
|
|
7
|
-
from django.db.models import
|
|
7
|
+
from django.db.models import (
|
|
8
|
+
DecimalField,
|
|
9
|
+
ExpressionWrapper,
|
|
10
|
+
F,
|
|
11
|
+
Q,
|
|
12
|
+
Sum,
|
|
13
|
+
Value,
|
|
14
|
+
)
|
|
8
15
|
from django.db.models.functions import Coalesce, Round
|
|
9
16
|
from django.utils import timezone
|
|
10
17
|
|
|
@@ -17,6 +24,7 @@ from eveuniverse.models import EveSolarSystem, EveType
|
|
|
17
24
|
|
|
18
25
|
# AA Ledger
|
|
19
26
|
from ledger import __title__
|
|
27
|
+
from ledger.app_settings import LEDGER_PRICE_PERCENTAGE
|
|
20
28
|
from ledger.decorators import log_timing
|
|
21
29
|
from ledger.helpers.etag import etag_results
|
|
22
30
|
from ledger.providers import esi
|
|
@@ -31,33 +39,46 @@ if TYPE_CHECKING:
|
|
|
31
39
|
logger = LoggerAddTag(get_extension_logger(__name__), __title__)
|
|
32
40
|
|
|
33
41
|
|
|
42
|
+
def require_valid_price_percentage(func):
|
|
43
|
+
def wrapper(*args, **kwargs):
|
|
44
|
+
if not isinstance(LEDGER_PRICE_PERCENTAGE, (int, float)):
|
|
45
|
+
raise ValueError("LEDGER_PRICE_PERCENTAGE must be a number")
|
|
46
|
+
if LEDGER_PRICE_PERCENTAGE <= 0:
|
|
47
|
+
raise ValueError("LEDGER_PRICE_PERCENTAGE must be positive")
|
|
48
|
+
return func(*args, **kwargs)
|
|
49
|
+
|
|
50
|
+
return wrapper
|
|
51
|
+
|
|
52
|
+
|
|
34
53
|
class CharacterMiningLedgerEntryQueryset(models.QuerySet):
|
|
54
|
+
@require_valid_price_percentage
|
|
35
55
|
def annotate_pricing(self) -> models.QuerySet:
|
|
36
56
|
"""Annotate price and total columns."""
|
|
37
|
-
return self.annotate(price=F("
|
|
57
|
+
return self.annotate(price=F("price_per_unit")).annotate(
|
|
38
58
|
total=ExpressionWrapper(
|
|
39
|
-
F("
|
|
59
|
+
(F("price_per_unit") * F("quantity")) * LEDGER_PRICE_PERCENTAGE,
|
|
40
60
|
output_field=models.DecimalField(),
|
|
41
61
|
),
|
|
42
62
|
)
|
|
43
63
|
|
|
44
|
-
def annotate_mining(self) -> models.QuerySet:
|
|
64
|
+
def annotate_mining(self, with_period: bool = False) -> models.QuerySet:
|
|
45
65
|
"""Annotate mining columns."""
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
.
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
),
|
|
59
|
-
|
|
60
|
-
)
|
|
66
|
+
qs = self.annotate_pricing()
|
|
67
|
+
values_fields = [
|
|
68
|
+
"character__eve_character__character_id",
|
|
69
|
+
"character__eve_character__character_name",
|
|
70
|
+
]
|
|
71
|
+
if with_period:
|
|
72
|
+
values_fields.append("period")
|
|
73
|
+
|
|
74
|
+
return qs.values(*values_fields).annotate(
|
|
75
|
+
mining_income=Round(
|
|
76
|
+
Coalesce(
|
|
77
|
+
Sum(F("total")),
|
|
78
|
+
Value(0),
|
|
79
|
+
output_field=DecimalField(),
|
|
80
|
+
),
|
|
81
|
+
precision=2,
|
|
61
82
|
)
|
|
62
83
|
)
|
|
63
84
|
|
|
@@ -186,6 +207,32 @@ class CharacterMiningLedgerEntryManagerBase(models.Manager):
|
|
|
186
207
|
if old_events:
|
|
187
208
|
self.bulk_update(old_events, fields=["quantity"])
|
|
188
209
|
|
|
210
|
+
self._update_mining_price(character)
|
|
211
|
+
|
|
212
|
+
def _update_mining_price(self, character: "CharacterAudit") -> None:
|
|
213
|
+
"""Update prices for mining ledger entries."""
|
|
214
|
+
# Update EveMarketPrice on a Daily basis
|
|
215
|
+
self.model.update_evemarket_price()
|
|
216
|
+
|
|
217
|
+
mining_ledger = character.mining_ledger.filter(price_per_unit__isnull=True)
|
|
218
|
+
logger.debug(
|
|
219
|
+
f"Checking {mining_ledger.count()} mining ledger entries for missing prices."
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
updated_entries = []
|
|
223
|
+
for entry in mining_ledger:
|
|
224
|
+
npc_price = entry.get_npc_price()
|
|
225
|
+
if npc_price is not None:
|
|
226
|
+
entry.price_per_unit = npc_price
|
|
227
|
+
updated_entries.append(entry)
|
|
228
|
+
|
|
229
|
+
if updated_entries:
|
|
230
|
+
self.bulk_update(updated_entries, fields=["price_per_unit"])
|
|
231
|
+
|
|
232
|
+
logger.debug(
|
|
233
|
+
f"Updated prices for {len(updated_entries)}({character.character_name}) mining ledger entries."
|
|
234
|
+
)
|
|
235
|
+
|
|
189
236
|
|
|
190
237
|
CharacterMiningLedgerEntryManager = CharacterMiningLedgerEntryManagerBase.from_queryset(
|
|
191
238
|
CharacterMiningLedgerEntryQueryset
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Generated by Django 4.2.23 on 2025-08-28 05:19
|
|
2
|
+
|
|
3
|
+
# Django
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
|
|
9
|
+
dependencies = [
|
|
10
|
+
("ledger", "0015_rename_character_characteraudit_eve_character"),
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
operations = [
|
|
14
|
+
migrations.AddField(
|
|
15
|
+
model_name="characterminingledger",
|
|
16
|
+
name="price_per_unit",
|
|
17
|
+
field=models.DecimalField(
|
|
18
|
+
decimal_places=2, default=None, max_digits=20, null=True
|
|
19
|
+
),
|
|
20
|
+
),
|
|
21
|
+
]
|
ledger/models/characteraudit.py
CHANGED
|
@@ -9,6 +9,7 @@ from collections.abc import Callable
|
|
|
9
9
|
from bravado.exception import HTTPInternalServerError
|
|
10
10
|
|
|
11
11
|
# Django
|
|
12
|
+
from django.core.cache import cache
|
|
12
13
|
from django.db import models
|
|
13
14
|
from django.utils import timezone
|
|
14
15
|
from django.utils.safestring import mark_safe
|
|
@@ -21,10 +22,11 @@ from esi.errors import TokenError
|
|
|
21
22
|
|
|
22
23
|
# Alliance Auth (External Libs)
|
|
23
24
|
from app_utils.logging import LoggerAddTag
|
|
24
|
-
from eveuniverse.models import EveSolarSystem, EveType
|
|
25
|
+
from eveuniverse.models import EveMarketPrice, EveSolarSystem, EveType
|
|
25
26
|
|
|
26
27
|
# AA Ledger
|
|
27
28
|
from ledger import __title__
|
|
29
|
+
from ledger.app_settings import LEDGER_CACHE_KEY, LEDGER_USE_COMPRESSED
|
|
28
30
|
from ledger.errors import HTTPGatewayTimeoutError, NotModifiedError, TokenDoesNotExist
|
|
29
31
|
from ledger.managers.character_audit_manager import (
|
|
30
32
|
CharacterAuditManager,
|
|
@@ -438,10 +440,39 @@ class CharacterMiningLedger(models.Model):
|
|
|
438
440
|
)
|
|
439
441
|
quantity = models.IntegerField()
|
|
440
442
|
|
|
443
|
+
price_per_unit = models.DecimalField(
|
|
444
|
+
max_digits=20, decimal_places=2, null=True, default=None
|
|
445
|
+
)
|
|
446
|
+
|
|
441
447
|
@staticmethod
|
|
442
448
|
def create_primary_key(character_id, mining_record):
|
|
443
449
|
return f"{mining_record['date'].strftime('%Y%m%d')}-{mining_record['type_id']}-{character_id}-{mining_record['solar_system_id']}"
|
|
444
450
|
|
|
451
|
+
@staticmethod
|
|
452
|
+
def update_evemarket_price(): # Dont want to make a task only for this
|
|
453
|
+
"""Update Prices for the EveMarketPrice."""
|
|
454
|
+
updated = 0
|
|
455
|
+
cached_update = cache.get(f"{LEDGER_CACHE_KEY}-eve-market-price", False)
|
|
456
|
+
if cached_update is False:
|
|
457
|
+
updated = EveMarketPrice.objects.update_from_esi()
|
|
458
|
+
cache.set(
|
|
459
|
+
f"{LEDGER_CACHE_KEY}-eve-market-price", None, (60 * 60 * 24)
|
|
460
|
+
) # Cache for 24 hours
|
|
461
|
+
logger.debug(f"Updated {updated} for entries EveMarketPrice")
|
|
462
|
+
return updated
|
|
463
|
+
|
|
464
|
+
def get_npc_price(self):
|
|
465
|
+
"""Get the NPC price for the type."""
|
|
466
|
+
try:
|
|
467
|
+
if LEDGER_USE_COMPRESSED:
|
|
468
|
+
type_name = f"Compressed {self.type.name}"
|
|
469
|
+
price = EveType.objects.get(name=type_name).market_price.average_price
|
|
470
|
+
else:
|
|
471
|
+
price = self.type.market_price.average_price
|
|
472
|
+
except (EveMarketPrice.DoesNotExist, EveType.DoesNotExist):
|
|
473
|
+
price = None
|
|
474
|
+
return price
|
|
475
|
+
|
|
445
476
|
objects = CharacterMiningLedgerEntryManager()
|
|
446
477
|
|
|
447
478
|
class Meta:
|
|
@@ -25,8 +25,6 @@ function load_or_create_Chart(div, data, chart) {
|
|
|
25
25
|
return createRattingBarChart(root, data, div);
|
|
26
26
|
} else if (chart === 'chart') {
|
|
27
27
|
return createChordChart(root, data, div);
|
|
28
|
-
} else if (chart === 'gauge') {
|
|
29
|
-
return createWorkflowGaugeChart(root, data, div);
|
|
30
28
|
}
|
|
31
29
|
|
|
32
30
|
return true;
|
|
@@ -39,12 +37,10 @@ function initCharts(data) {
|
|
|
39
37
|
// Dispose of existing Root instances with the same id if they exist
|
|
40
38
|
const rootChartId = 'rattingChart';
|
|
41
39
|
const rootBarId = 'rattingBar';
|
|
42
|
-
//const rootGaugeId = 'rattingworkGauge';
|
|
43
40
|
|
|
44
41
|
// Create the chart
|
|
45
42
|
const barChart = load_or_create_Chart(rootBarId, billboard.rattingbar, 'bar');
|
|
46
43
|
const chart = load_or_create_Chart(rootChartId, billboard.charts, 'chart');
|
|
47
|
-
//const gaugeChart = load_or_create_Chart(rootGaugeId, billboard.workflowgauge, 'gauge');
|
|
48
44
|
}
|
|
49
45
|
|
|
50
46
|
function createChordChart(root, data, id) {
|
|
@@ -128,132 +124,6 @@ function createChordChart(root, data, id) {
|
|
|
128
124
|
series.appear(1000, 100);
|
|
129
125
|
}
|
|
130
126
|
|
|
131
|
-
function createRattingChart(root, data, id) {
|
|
132
|
-
if (!data || !Array.isArray(data.series)) {
|
|
133
|
-
console.log('Data is not in the expected format:', data);
|
|
134
|
-
disposeRoot(id);
|
|
135
|
-
$('#ChartContainer').addClass('d-none');
|
|
136
|
-
$('#ChartContainer').removeClass('active');
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Store the root object globally
|
|
141
|
-
window.chartsRoots = window.chartRoots || {};
|
|
142
|
-
window.chartsRoots[id] = root;
|
|
143
|
-
|
|
144
|
-
let chart = root.container.children.values.find(child => child instanceof am5xy.XYChart);
|
|
145
|
-
if (chart) {
|
|
146
|
-
// Update existing chart data
|
|
147
|
-
chart.series.values[0].data.setAll(data.series);
|
|
148
|
-
} else {
|
|
149
|
-
// Create a new chart
|
|
150
|
-
chart = root.container.children.push(am5percent.PieChart.new(root, {
|
|
151
|
-
innerRadius: am5.percent(50),
|
|
152
|
-
layout: root.verticalLayout
|
|
153
|
-
}));
|
|
154
|
-
|
|
155
|
-
const series = chart.series.push(am5percent.PieSeries.new(root, {
|
|
156
|
-
valueField: 'value',
|
|
157
|
-
categoryField: 'category',
|
|
158
|
-
alignLabels: false,
|
|
159
|
-
}));
|
|
160
|
-
|
|
161
|
-
const colorSet = am5.ColorSet.new(root, {
|
|
162
|
-
colors: [series.get('colors').getIndex(0)], passOptions: { lightness: -0.05, hue: 0 }
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
series.states.create('hidden', { startAngle: 180, endAngle: 180 });
|
|
166
|
-
|
|
167
|
-
series.slices.template.setAll({
|
|
168
|
-
templateField: 'sliceSettings',
|
|
169
|
-
strokeOpacity: 0,
|
|
170
|
-
tooltipText: '{category}: {valuePercentTotal.formatNumber("0.00")}% ({value} ISK)',
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
// Labels for category names outside the pie chart
|
|
174
|
-
series.labels.template.setAll({
|
|
175
|
-
textType: 'circular',
|
|
176
|
-
centerX: 0,
|
|
177
|
-
centerY: 0,
|
|
178
|
-
text: '' // Display only the category name
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
// Transform the data to the required format
|
|
182
|
-
var transformedData = [];
|
|
183
|
-
var seriesData = data.series[0];
|
|
184
|
-
for (var category in seriesData) {
|
|
185
|
-
if (category !== 'date') {
|
|
186
|
-
transformedData.push({
|
|
187
|
-
category: category,
|
|
188
|
-
value: seriesData[category].value,
|
|
189
|
-
percentage: seriesData[category].percentage,
|
|
190
|
-
mode: seriesData[category].mode
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
const legend = chart.children.push(am5.Legend.new(root, {
|
|
196
|
-
centerX: am5.percent(50),
|
|
197
|
-
x: am5.percent(50),
|
|
198
|
-
centerY: am5.percent(100),
|
|
199
|
-
y: am5.percent(100),
|
|
200
|
-
layout: am5.GridLayout.new(root, {
|
|
201
|
-
maxColumns: 5,
|
|
202
|
-
fixedWidthGrid: true
|
|
203
|
-
})
|
|
204
|
-
}));
|
|
205
|
-
|
|
206
|
-
// Increase the spacing between legend items
|
|
207
|
-
legend.itemContainers.template.setAll({
|
|
208
|
-
paddingTop: 10,
|
|
209
|
-
paddingBottom: 10,
|
|
210
|
-
paddingLeft: 10,
|
|
211
|
-
paddingRight: 10
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
series.data.setAll(transformedData);
|
|
215
|
-
|
|
216
|
-
legend.labels.template.setAll({
|
|
217
|
-
text: '{category}', // Display the category name and mode symbol in the legend
|
|
218
|
-
});
|
|
219
|
-
|
|
220
|
-
legend.valueLabels.template.setAll({
|
|
221
|
-
text: '' // Hide the percentage values in the legend
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
// Set custom markers for legend items
|
|
225
|
-
legend.markers.template.setup = function(marker) {
|
|
226
|
-
marker.events.on('dataitemchanged', function() {
|
|
227
|
-
var dataItem = marker._dataItem;
|
|
228
|
-
var series = dataItem.dataContext;
|
|
229
|
-
var iconColor = series.dataContext.mode === 'income' ? 'income' : 'cost';
|
|
230
|
-
marker.children.push(am5.Picture.new(root, {
|
|
231
|
-
width: 64,
|
|
232
|
-
height: 64,
|
|
233
|
-
src: '/static/ledger/images/' + iconColor + '.png',
|
|
234
|
-
centerX: am5.percent(35),
|
|
235
|
-
centerY: am5.percent(35),
|
|
236
|
-
x: am5.percent(-50),
|
|
237
|
-
}));
|
|
238
|
-
|
|
239
|
-
dataItem.on('markerRectangle', function(rectangle) {
|
|
240
|
-
rectangle.set('forceHidden', true);
|
|
241
|
-
});
|
|
242
|
-
});
|
|
243
|
-
};
|
|
244
|
-
|
|
245
|
-
legend.data.setAll(series.dataItems);
|
|
246
|
-
|
|
247
|
-
// Remove Hide the chart container
|
|
248
|
-
$('#ChartContainer').removeClass('d-none');
|
|
249
|
-
$('#ChartContainer').addClass('active');
|
|
250
|
-
|
|
251
|
-
series.appear();
|
|
252
|
-
chart.appear(1000, 100);
|
|
253
|
-
}
|
|
254
|
-
return chart;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
127
|
function createRattingBarChart(root, data, id) {
|
|
258
128
|
if (!data || !Array.isArray(data.series)) {
|
|
259
129
|
console.debug('Data is not in the expected format:', data);
|
|
@@ -333,8 +203,13 @@ function createRattingBarChart(root, data, id) {
|
|
|
333
203
|
legend.data.push(series);
|
|
334
204
|
}
|
|
335
205
|
|
|
336
|
-
// Use categories from the data
|
|
337
|
-
data.categories
|
|
206
|
+
// Use categories from the data (now as array of dicts: {name, label})
|
|
207
|
+
if (Array.isArray(data.categories) && typeof data.categories[0] === 'object') {
|
|
208
|
+
data.categories.forEach((cat) => makeSeries(cat.label || cat.label, cat.name));
|
|
209
|
+
} else {
|
|
210
|
+
// fallback for old format (array of strings)
|
|
211
|
+
data.categories.forEach((name) => makeSeries(name, name));
|
|
212
|
+
}
|
|
338
213
|
|
|
339
214
|
// Remove Hide the chart container
|
|
340
215
|
$('#rattingBarContainer').removeClass('d-none');
|
|
@@ -344,98 +219,3 @@ function createRattingBarChart(root, data, id) {
|
|
|
344
219
|
}
|
|
345
220
|
return chart;
|
|
346
221
|
}
|
|
347
|
-
|
|
348
|
-
function createWorkflowGaugeChart(root, data, id) {
|
|
349
|
-
if (!data || !Array.isArray(data.series)) {
|
|
350
|
-
console.debug('Data is not in the expected format:', data);
|
|
351
|
-
disposeRoot(id);
|
|
352
|
-
$('#workGaugeContainer').addClass('d-none');
|
|
353
|
-
$('#workGaugeContainer').removeClass('active');
|
|
354
|
-
return;
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
// Store the root object globally
|
|
358
|
-
window.gaugesRoots = window.gaugesRoots || {};
|
|
359
|
-
window.gaugesRoots[id] = root;
|
|
360
|
-
|
|
361
|
-
const chart = root.container.children.push(am5percent.PieChart.new(root, {
|
|
362
|
-
startAngle: 160, endAngle: 380
|
|
363
|
-
}));
|
|
364
|
-
|
|
365
|
-
const series = chart.series.push(am5percent.PieSeries.new(root, {
|
|
366
|
-
valueField: 'value',
|
|
367
|
-
categoryField: 'category',
|
|
368
|
-
startAngle: 180,
|
|
369
|
-
endAngle: 360,
|
|
370
|
-
radius: am5.percent(95),
|
|
371
|
-
innerRadius: am5.percent(50),
|
|
372
|
-
alignLabels: false,
|
|
373
|
-
}));
|
|
374
|
-
|
|
375
|
-
const colorSet = am5.ColorSet.new(root, {
|
|
376
|
-
colors: [series.get('colors').getIndex(0)], passOptions: { lightness: -0.05, hue: 0 }
|
|
377
|
-
});
|
|
378
|
-
|
|
379
|
-
series.states.create('hidden', { startAngle: 180, endAngle: 180 });
|
|
380
|
-
|
|
381
|
-
const legend = chart.children.push(am5.Legend.new(root, {
|
|
382
|
-
centerX: am5.percent(50),
|
|
383
|
-
x: am5.percent(50),
|
|
384
|
-
centerY: am5.percent(100),
|
|
385
|
-
y: am5.percent(100),
|
|
386
|
-
marginTop: 15,
|
|
387
|
-
marginBottom: 15
|
|
388
|
-
}));
|
|
389
|
-
|
|
390
|
-
series.slices.template.setAll({
|
|
391
|
-
templateField: 'sliceSettings',
|
|
392
|
-
strokeOpacity: 0
|
|
393
|
-
});
|
|
394
|
-
|
|
395
|
-
series.labels.template.setAll({
|
|
396
|
-
textType: 'circular',
|
|
397
|
-
text: '',
|
|
398
|
-
radius: am5.percent(-30),
|
|
399
|
-
inside: false,
|
|
400
|
-
centerX: am5.percent(50),
|
|
401
|
-
centerY: am5.percent(50),
|
|
402
|
-
});
|
|
403
|
-
|
|
404
|
-
series.labels.template.adapters.add('radius', function (radius, target) {
|
|
405
|
-
var dataItem = target.dataItem;
|
|
406
|
-
var slice = dataItem.get('slice');
|
|
407
|
-
return -(slice.get('radius') - slice.get('innerRadius')) / 2 - 10;
|
|
408
|
-
});
|
|
409
|
-
|
|
410
|
-
// Transform the data to the required format
|
|
411
|
-
var transformedData = [];
|
|
412
|
-
var seriesData = data.series[0];
|
|
413
|
-
for (var category in seriesData) {
|
|
414
|
-
if (category !== 'date') {
|
|
415
|
-
transformedData.push({
|
|
416
|
-
category: category,
|
|
417
|
-
value: seriesData[category].value,
|
|
418
|
-
mode: seriesData[category].mode
|
|
419
|
-
});
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
series.data.setAll(transformedData);
|
|
424
|
-
|
|
425
|
-
legend.labels.template.setAll({
|
|
426
|
-
text: '{category}', // Display the category name and mode symbol in the legend
|
|
427
|
-
});
|
|
428
|
-
|
|
429
|
-
legend.valueLabels.template.setAll({
|
|
430
|
-
text: '' // Hide the percentage values in the legend
|
|
431
|
-
});
|
|
432
|
-
|
|
433
|
-
legend.data.setAll(series.dataItems);
|
|
434
|
-
|
|
435
|
-
$('#workGaugeContainer').removeClass('d-none');
|
|
436
|
-
$('#workGaugeContainer').addClass('active');
|
|
437
|
-
|
|
438
|
-
series.appear();
|
|
439
|
-
chart.appear(1000, 100);
|
|
440
|
-
return chart;
|
|
441
|
-
}
|
ledger/tasks.py
CHANGED
|
@@ -209,7 +209,6 @@ def update_character(character_pk: int, force_refresh=False):
|
|
|
209
209
|
|
|
210
210
|
|
|
211
211
|
@shared_task(**_update_ledger_char_params)
|
|
212
|
-
@when_esi_is_available
|
|
213
212
|
def update_char_wallet_journal(character_pk: int, force_refresh: bool):
|
|
214
213
|
return _update_character_section(
|
|
215
214
|
character_pk,
|
|
@@ -219,7 +218,6 @@ def update_char_wallet_journal(character_pk: int, force_refresh: bool):
|
|
|
219
218
|
|
|
220
219
|
|
|
221
220
|
@shared_task(**_update_ledger_char_params)
|
|
222
|
-
@when_esi_is_available
|
|
223
221
|
def update_char_mining_ledger(character_pk: int, force_refresh: bool):
|
|
224
222
|
return _update_character_section(
|
|
225
223
|
character_pk,
|
|
@@ -229,7 +227,6 @@ def update_char_mining_ledger(character_pk: int, force_refresh: bool):
|
|
|
229
227
|
|
|
230
228
|
|
|
231
229
|
@shared_task(**_update_ledger_char_params)
|
|
232
|
-
@when_esi_is_available
|
|
233
230
|
def update_char_planets(character_pk: int, force_refresh: bool):
|
|
234
231
|
logger.debug("Updating Planet Data for %s", character_pk)
|
|
235
232
|
return _update_character_section(
|
|
@@ -240,7 +237,6 @@ def update_char_planets(character_pk: int, force_refresh: bool):
|
|
|
240
237
|
|
|
241
238
|
|
|
242
239
|
@shared_task(**_update_ledger_char_params)
|
|
243
|
-
@when_esi_is_available
|
|
244
240
|
def update_char_planets_details(character_pk: int, force_refresh: bool):
|
|
245
241
|
logger.debug("Updating Planet Details for %s", character_pk)
|
|
246
242
|
return _update_character_section(
|
|
@@ -371,7 +367,6 @@ def update_corporation(
|
|
|
371
367
|
|
|
372
368
|
|
|
373
369
|
@shared_task(**_update_ledger_corp_params)
|
|
374
|
-
@when_esi_is_available
|
|
375
370
|
def update_corp_wallet_division_names(corporation_pk: int, force_refresh: bool):
|
|
376
371
|
return _update_corporation_section(
|
|
377
372
|
corporation_pk,
|
|
@@ -381,7 +376,6 @@ def update_corp_wallet_division_names(corporation_pk: int, force_refresh: bool):
|
|
|
381
376
|
|
|
382
377
|
|
|
383
378
|
@shared_task(**_update_ledger_corp_params)
|
|
384
|
-
@when_esi_is_available
|
|
385
379
|
def update_corp_wallet_division(corporation_pk: int, force_refresh: bool):
|
|
386
380
|
return _update_corporation_section(
|
|
387
381
|
corporation_pk,
|
|
@@ -391,7 +385,6 @@ def update_corp_wallet_division(corporation_pk: int, force_refresh: bool):
|
|
|
391
385
|
|
|
392
386
|
|
|
393
387
|
@shared_task(**_update_ledger_corp_params)
|
|
394
|
-
@when_esi_is_available
|
|
395
388
|
def update_corp_wallet_journal(corporation_pk: int, force_refresh: bool):
|
|
396
389
|
return _update_corporation_section(
|
|
397
390
|
corporation_pk,
|
|
@@ -440,7 +433,7 @@ def clear_all_etags():
|
|
|
440
433
|
|
|
441
434
|
default_cache = caches["default"]
|
|
442
435
|
_client = default_cache.get_master_client()
|
|
443
|
-
keys = _client.keys(":?:
|
|
436
|
+
keys = _client.keys(f":?:{app_settings.LEDGER_CACHE_KEY}-*")
|
|
444
437
|
logger.info("Deleting %s etag keys", len(keys))
|
|
445
438
|
if keys:
|
|
446
439
|
deleted = _client.delete(*keys)
|
|
@@ -17,15 +17,24 @@
|
|
|
17
17
|
<h3 class="me-3">{% translate "Administration" %}</h3>
|
|
18
18
|
</div>
|
|
19
19
|
<!-- Content -->
|
|
20
|
-
<div class="card-body">
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
<div id="ledger-index" class="card-body rounded-bottom fade">
|
|
21
|
+
<div class="card-body">
|
|
22
|
+
<div class="row">
|
|
23
|
+
<div class="col-lg-6 col-md-12">
|
|
24
|
+
{% include 'ledger/partials/administration/dashboard.html' %}
|
|
25
|
+
</div>
|
|
26
|
+
<div class="col-lg-6 col-md-12">
|
|
27
|
+
{% include 'ledger/partials/administration/alliance.html' %}
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
26
30
|
</div>
|
|
27
|
-
<div class="card-body
|
|
28
|
-
|
|
31
|
+
<div class="card-body">
|
|
32
|
+
<div class="card-header bg-primary rounded-top d-flex align-items-center mt-4">
|
|
33
|
+
<h3 class="text-white">{% translate "Corporations" %}</h3>
|
|
34
|
+
</div>
|
|
35
|
+
<div class="card-body bg-secondary">
|
|
36
|
+
{% include 'ledger/partials/administration/alliance_corporations.html' %}
|
|
37
|
+
</div>
|
|
29
38
|
</div>
|
|
30
39
|
</div>
|
|
31
40
|
</div>
|