From 8d73fe3ed1fbdd7c21951408bc22a89d4be21489 Mon Sep 17 00:00:00 2001 From: Sirttas Date: Fri, 3 Jul 2026 14:00:42 +0200 Subject: [PATCH] feat(#8): Handle polymorphic activity source --- docs/mammon-api.yml | 66 ++++++++++++++++----- src/activity/SourceLabel.vue | 32 ++++++++++ src/activity/index.ts | 1 + src/corporations/CorporationLabel.vue | 19 ++++++ src/corporations/index.ts | 1 + src/generated/mammon/api.ts | 44 +++++++++++--- src/market/acquisition/acquisition.ts | 4 +- src/pages/ledger/ListLedgerTransactions.vue | 18 +++--- 8 files changed, 154 insertions(+), 31 deletions(-) create mode 100644 src/activity/SourceLabel.vue create mode 100644 src/activity/index.ts create mode 100644 src/corporations/CorporationLabel.vue create mode 100644 src/corporations/index.ts diff --git a/docs/mammon-api.yml b/docs/mammon-api.yml index 295d05c..a5ee825 100644 --- a/docs/mammon-api.yml +++ b/docs/mammon-api.yml @@ -1499,6 +1499,46 @@ components: type: string required: - type + ActivitySourceResponse: + type: object + description: "Where an activity or transaction came from: a character, a corporation\ + \ wallet, or nothing (a manual entry)." + properties: + type: + type: string + description: The kind of source. + enum: + - CHARACTER + - CORPORATION + - NONE + example: CHARACTER + characterId: + type: + - integer + - "null" + format: int64 + description: "EVE character id, when the source is a character." + example: 2112625428 + corporationId: + type: + - integer + - "null" + format: int64 + description: "EVE corporation id, when the source is a corporation." + example: 98000001 + division: + type: + - integer + - "null" + format: int32 + description: "Corporation wallet division (1-7), when the source is a corporation\ + \ and it is known." + example: 4 + required: + - characterId + - corporationId + - division + - type IskTransferResponse: allOf: - $ref: "#/components/schemas/TransferResponse" @@ -1563,13 +1603,10 @@ components: format: uuid description: Unique transaction identifier. example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 - characterId: - type: - - integer - - "null" - format: int64 - description: "EVE character id the transaction is attributed to, if any." - example: 2112625428 + source: + $ref: "#/components/schemas/ActivitySourceResponse" + description: "Where the transaction is attributed: a character, a corporation,\ + \ or nothing." datetime: type: string format: date-time @@ -1585,9 +1622,9 @@ components: items: $ref: "#/components/schemas/TransferResponse" required: - - characterId - datetime - description + - source - transactionId - transfers TransferResponse: @@ -1649,17 +1686,16 @@ components: format: uuid description: Unique acquisition identifier. example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 - characterId: - type: integer - format: int64 - description: EVE character id that made the acquisition. - example: 2112625428 + source: + $ref: "#/components/schemas/ActivitySourceResponse" + description: "Where the acquisition came from: a character, a corporation,\ + \ or nothing." marketTypeId: type: integer format: int64 description: EVE market type (item) id that was acquired. example: 34 - source: + origin: type: string description: How the item entered the inventory. enum: @@ -1686,9 +1722,9 @@ components: example: 5.42 required: - acquisitionId - - characterId - datetime - marketTypeId + - origin - quantity - remaining - source diff --git a/src/activity/SourceLabel.vue b/src/activity/SourceLabel.vue new file mode 100644 index 0000000..8ef72f9 --- /dev/null +++ b/src/activity/SourceLabel.vue @@ -0,0 +1,32 @@ + + + diff --git a/src/activity/index.ts b/src/activity/index.ts new file mode 100644 index 0000000..389d889 --- /dev/null +++ b/src/activity/index.ts @@ -0,0 +1 @@ +export {default as SourceLabel} from './SourceLabel.vue'; diff --git a/src/corporations/CorporationLabel.vue b/src/corporations/CorporationLabel.vue new file mode 100644 index 0000000..d1b2a19 --- /dev/null +++ b/src/corporations/CorporationLabel.vue @@ -0,0 +1,19 @@ + + + diff --git a/src/corporations/index.ts b/src/corporations/index.ts new file mode 100644 index 0000000..5b1d9a6 --- /dev/null +++ b/src/corporations/index.ts @@ -0,0 +1 @@ +export {default as CorporationLabel} from './CorporationLabel.vue'; diff --git a/src/generated/mammon/api.ts b/src/generated/mammon/api.ts index b59ad67..f512f93 100644 --- a/src/generated/mammon/api.ts +++ b/src/generated/mammon/api.ts @@ -32,9 +32,9 @@ export interface AcquisitionResponse { */ 'acquisitionId': string; /** - * EVE character id that made the acquisition. + * Where the acquisition came from: a character, a corporation, or nothing. */ - 'characterId': number; + 'source': ActivitySourceResponse; /** * EVE market type (item) id that was acquired. */ @@ -42,7 +42,7 @@ export interface AcquisitionResponse { /** * How the item entered the inventory. */ - 'source': AcquisitionResponseSourceEnum; + 'origin': AcquisitionResponseOriginEnum; /** * When the acquisition occurred. */ @@ -61,12 +61,42 @@ export interface AcquisitionResponse { 'unitCost': number; } -export const AcquisitionResponseSourceEnum = { +export const AcquisitionResponseOriginEnum = { Bought: 'BOUGHT', Manual: 'MANUAL', } as const; -export type AcquisitionResponseSourceEnum = typeof AcquisitionResponseSourceEnum[keyof typeof AcquisitionResponseSourceEnum]; +export type AcquisitionResponseOriginEnum = typeof AcquisitionResponseOriginEnum[keyof typeof AcquisitionResponseOriginEnum]; + +/** + * Where an activity or transaction came from: a character, a corporation wallet, or nothing (a manual entry). + */ +export interface ActivitySourceResponse { + /** + * The kind of source. + */ + 'type': ActivitySourceResponseTypeEnum; + /** + * EVE character id, when the source is a character. + */ + 'characterId': number | null; + /** + * EVE corporation id, when the source is a corporation. + */ + 'corporationId': number | null; + /** + * Corporation wallet division (1-7), when the source is a corporation and it is known. + */ + 'division': number | null; +} + +export const ActivitySourceResponseTypeEnum = { + Character: 'CHARACTER', + Corporation: 'CORPORATION', + None: 'NONE', +} as const; + +export type ActivitySourceResponseTypeEnum = typeof ActivitySourceResponseTypeEnum[keyof typeof ActivitySourceResponseTypeEnum]; /** * The balance of a ledger: its ISK total plus the quantity of each item type held. @@ -604,9 +634,9 @@ export interface TransactionResponse { */ 'transactionId': string; /** - * EVE character id the transaction is attributed to, if any. + * Where the transaction is attributed: a character, a corporation, or nothing. */ - 'characterId': number | null; + 'source': ActivitySourceResponse; /** * When the transaction occurred. */ diff --git a/src/market/acquisition/acquisition.ts b/src/market/acquisition/acquisition.ts index 513c454..02ea897 100644 --- a/src/market/acquisition/acquisition.ts +++ b/src/market/acquisition/acquisition.ts @@ -1,7 +1,7 @@ import {defineStore} from "pinia"; import {computed, ref} from "vue"; import {acquisitionApi} from "@/mammon"; -import {AcquisitionResponse, AcquisitionResponseSourceEnum} from "@/generated/mammon"; +import {AcquisitionResponse, ActivitySourceResponse} from "@/generated/mammon"; export type AcquiredTypeSource = 'bo' | 'so' | 'prod' | 'misc'; @@ -12,7 +12,7 @@ export type RawAcquiredType = { remaining: number; price: number; date: Date; - source: AcquisitionResponseSourceEnum; + source: ActivitySourceResponse; } const toAcquiredType = (a: AcquisitionResponse): RawAcquiredType => ({ diff --git a/src/pages/ledger/ListLedgerTransactions.vue b/src/pages/ledger/ListLedgerTransactions.vue index aa1b027..0df4889 100644 --- a/src/pages/ledger/ListLedgerTransactions.vue +++ b/src/pages/ledger/ListLedgerTransactions.vue @@ -2,12 +2,13 @@ import {findAllTransactionInLeger, useLedgerParam} from "@/ledger"; import {computedAsync} from "@vueuse/core"; -import {TransactionResponse} from "@/generated/mammon"; +import {ActivitySourceResponseTypeEnum, TransactionResponse} from "@/generated/mammon"; import {IskLabel} from "@/market"; import {SortableHeader, useSort, VirtualScrollTable} from "@/components/table"; import {TransferList, TransferTypes} from "@/transaction"; import {Dropdown} from "@/components"; -import {CharacterLabel, useCharactersStore} from "@/characters"; +import {SourceLabel} from "@/activity"; +import {useCharactersStore} from "@/characters"; import {formatEveDate} from "@/formaters.ts"; const {ledgerId} = useLedgerParam(); @@ -21,10 +22,13 @@ const transactions = computedAsync(async () => { }, []); const { sortedArray, headerProps } = useSort(computedAsync(() => Promise.all(transactions.value.map(async transaction => { - const character = await charactersStore.findById(transaction.characterId); + const source = transaction.source; + const character = source.type === ActivitySourceResponseTypeEnum.Character && source.characterId + ? await charactersStore.findById(source.characterId) + : undefined; return { - character, - characterName: character?.name ?? "", + source, + sourceName: character?.name ?? (source.type === ActivitySourceResponseTypeEnum.Corporation ? "Corporation" : ""), transactionId: transaction.transactionId, description: transaction.description, date: new Date(transaction.datetime), @@ -59,7 +63,7 @@ const getIskBalance = (transaction: TransactionResponse) => {