diff --git a/docs/mammon-api.yml b/docs/mammon-api.yml index ae3fe00..e292c3a 100644 --- a/docs/mammon-api.yml +++ b/docs/mammon-api.yml @@ -350,6 +350,46 @@ paths: description: New activities fetched and stored "400": description: No character with this id + /activity/consume: + post: + tags: + - activity + summary: Manually record a consumption (sell) of an item. Call POST /activities/process + to fold it into acquisitions. + operationId: consume + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/ManualActivityRequest" + required: true + responses: + "200": + description: Consumption recorded + "400": + description: Invalid request (e.g. CORPORATION source) + "404": + description: Source not owned by the caller + /activity/acquire: + post: + tags: + - activity + summary: Manually record an acquisition (buy) of an item. Call POST /activities/process + to fold it into acquisitions. + operationId: acquire + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/ManualActivityRequest" + required: true + responses: + "200": + description: Acquisition recorded + "400": + description: Invalid request (e.g. CORPORATION source) + "404": + description: Source not owned by the caller /activities/process: post: tags: @@ -1123,6 +1163,84 @@ components: required: - memberLedgerIds - name + ActivitySourceRequest: + type: object + description: "Where a manual activity is attributed: a character, a ledger,\ + \ or nothing. CORPORATION is not accepted." + properties: + type: + type: string + description: The kind of source. + enum: + - CHARACTER + - LEDGER + - NONE + example: CHARACTER + characterId: + type: + - integer + - "null" + format: int64 + description: "EVE character id, when the source is a character." + example: 2112625428 + ledgerId: + type: + - string + - "null" + format: uuid + description: "Ledger id, when the source is a ledger." + example: 0199a1b2-c3d4-7e5f-8a90-1b2c3d4e5f60 + required: + - characterId + - ledgerId + - type + ManualActivityRequest: + type: object + description: Request to manually record an acquisition (buy) or consumption + (sell) of an item. + properties: + source: + $ref: "#/components/schemas/ActivitySourceRequest" + description: Where the activity is attributed. + marketTypeId: + type: integer + format: int64 + description: EVE type id of the traded item. + example: 34 + quantity: + type: integer + format: int64 + description: Number of units. + example: 1000 + unitPrice: + type: number + description: Price per unit. + example: 5.42 + datetime: + type: + - string + - "null" + format: date-time + description: When the activity happened. Defaults to now when omitted. + taxes: + type: + - number + - "null" + description: Taxes paid. Defaults to 0 when omitted. + example: 0 + description: + type: + - string + - "null" + description: Free-form description. + required: + - datetime + - description + - marketTypeId + - quantity + - source + - taxes + - unitPrice CharacterResponse: type: object description: An EVE Online character. @@ -1507,7 +1625,7 @@ components: ActivitySourceResponse: type: object description: "Where an activity or transaction came from: a character, a corporation\ - \ wallet, or nothing (a manual entry)." + \ wallet, a ledger, or nothing (a manual entry)." properties: type: type: string @@ -1515,6 +1633,7 @@ components: enum: - CHARACTER - CORPORATION + - LEDGER - NONE example: CHARACTER characterId: @@ -1539,10 +1658,18 @@ components: description: "Corporation wallet division (1-7), when the source is a corporation\ \ and it is known." example: 4 + ledgerId: + type: + - string + - "null" + format: uuid + description: "Ledger id, when the source is a ledger." + example: 0199a1b2-c3d4-7e5f-8a90-1b2c3d4e5f60 required: - characterId - corporationId - division + - ledgerId - type IskTransferResponse: allOf: diff --git a/src/generated/mammon/api.ts b/src/generated/mammon/api.ts index 7897d4b..39fa313 100644 --- a/src/generated/mammon/api.ts +++ b/src/generated/mammon/api.ts @@ -61,7 +61,33 @@ export interface AcquisitionResponse { 'unitCost': number; } /** - * Where an activity or transaction came from: a character, a corporation wallet, or nothing (a manual entry). + * Where a manual activity is attributed: a character, a ledger, or nothing. CORPORATION is not accepted. + */ +export interface ActivitySourceRequest { + /** + * The kind of source. + */ + 'type': ActivitySourceRequestTypeEnum; + /** + * EVE character id, when the source is a character. + */ + 'characterId': number | null; + /** + * Ledger id, when the source is a ledger. + */ + 'ledgerId': string | null; +} + +export const ActivitySourceRequestTypeEnum = { + Character: 'CHARACTER', + Ledger: 'LEDGER', + None: 'NONE', +} as const; + +export type ActivitySourceRequestTypeEnum = typeof ActivitySourceRequestTypeEnum[keyof typeof ActivitySourceRequestTypeEnum]; + +/** + * Where an activity or transaction came from: a character, a corporation wallet, a ledger, or nothing (a manual entry). */ export interface ActivitySourceResponse { /** @@ -80,11 +106,16 @@ export interface ActivitySourceResponse { * Corporation wallet division (1-7), when the source is a corporation and it is known. */ 'division': number | null; + /** + * Ledger id, when the source is a ledger. + */ + 'ledgerId': string | null; } export const ActivitySourceResponseTypeEnum = { Character: 'CHARACTER', Corporation: 'CORPORATION', + Ledger: 'LEDGER', None: 'NONE', } as const; @@ -271,6 +302,39 @@ export interface MainLedgerResponse extends LedgerResponse { */ 'balance': number; } +/** + * Request to manually record an acquisition (buy) or consumption (sell) of an item. + */ +export interface ManualActivityRequest { + /** + * Where the activity is attributed. + */ + 'source': ActivitySourceRequest; + /** + * EVE type id of the traded item. + */ + 'marketTypeId': number; + /** + * Number of units. + */ + 'quantity': number; + /** + * Price per unit. + */ + 'unitPrice': number; + /** + * When the activity happened. Defaults to now when omitted. + */ + 'datetime': string | null; + /** + * Taxes paid. Defaults to 0 when omitted. + */ + 'taxes': number | null; + /** + * Free-form description. + */ + 'description': string | null; +} /** * A single day of market history for a market type. */ @@ -803,6 +867,74 @@ export class AcquisitionApi extends BaseAPI { */ export const ActivityApiAxiosParamCreator = function (configuration?: Configuration) { return { + /** + * + * @summary Manually record an acquisition (buy) of an item. Call POST /activities/process to fold it into acquisitions. + * @param {ManualActivityRequest} manualActivityRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + acquire: async (manualActivityRequest: ManualActivityRequest, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'manualActivityRequest' is not null or undefined + assertParamExists('acquire', 'manualActivityRequest', manualActivityRequest) + const localVarPath = `/activity/acquire`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(manualActivityRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Manually record a consumption (sell) of an item. Call POST /activities/process to fold it into acquisitions. + * @param {ManualActivityRequest} manualActivityRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + consume: async (manualActivityRequest: ManualActivityRequest, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'manualActivityRequest' is not null or undefined + assertParamExists('consume', 'manualActivityRequest', manualActivityRequest) + const localVarPath = `/activity/consume`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(manualActivityRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, /** * * @summary Fetch new activities for the authenticated user\'s characters from the EVE API @@ -903,6 +1035,32 @@ export const ActivityApiAxiosParamCreator = function (configuration?: Configurat export const ActivityApiFp = function(configuration?: Configuration) { const localVarAxiosParamCreator = ActivityApiAxiosParamCreator(configuration) return { + /** + * + * @summary Manually record an acquisition (buy) of an item. Call POST /activities/process to fold it into acquisitions. + * @param {ManualActivityRequest} manualActivityRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async acquire(manualActivityRequest: ManualActivityRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.acquire(manualActivityRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['ActivityApi.acquire']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @summary Manually record a consumption (sell) of an item. Call POST /activities/process to fold it into acquisitions. + * @param {ManualActivityRequest} manualActivityRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async consume(manualActivityRequest: ManualActivityRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.consume(manualActivityRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['ActivityApi.consume']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, /** * * @summary Fetch new activities for the authenticated user\'s characters from the EVE API @@ -949,6 +1107,26 @@ export const ActivityApiFp = function(configuration?: Configuration) { export const ActivityApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { const localVarFp = ActivityApiFp(configuration) return { + /** + * + * @summary Manually record an acquisition (buy) of an item. Call POST /activities/process to fold it into acquisitions. + * @param {ManualActivityRequest} manualActivityRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + acquire(manualActivityRequest: ManualActivityRequest, options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.acquire(manualActivityRequest, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Manually record a consumption (sell) of an item. Call POST /activities/process to fold it into acquisitions. + * @param {ManualActivityRequest} manualActivityRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + consume(manualActivityRequest: ManualActivityRequest, options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.consume(manualActivityRequest, options).then((request) => request(axios, basePath)); + }, /** * * @summary Fetch new activities for the authenticated user\'s characters from the EVE API @@ -984,6 +1162,28 @@ export const ActivityApiFactory = function (configuration?: Configuration, baseP * ActivityApi - object-oriented interface */ export class ActivityApi extends BaseAPI { + /** + * + * @summary Manually record an acquisition (buy) of an item. Call POST /activities/process to fold it into acquisitions. + * @param {ManualActivityRequest} manualActivityRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + public acquire(manualActivityRequest: ManualActivityRequest, options?: RawAxiosRequestConfig) { + return ActivityApiFp(this.configuration).acquire(manualActivityRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Manually record a consumption (sell) of an item. Call POST /activities/process to fold it into acquisitions. + * @param {ManualActivityRequest} manualActivityRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + public consume(manualActivityRequest: ManualActivityRequest, options?: RawAxiosRequestConfig) { + return ActivityApiFp(this.configuration).consume(manualActivityRequest, options).then((request) => request(this.axios, this.basePath)); + } + /** * * @summary Fetch new activities for the authenticated user\'s characters from the EVE API diff --git a/src/market/acquisition/AcquiredType.ts b/src/market/acquisition/AcquiredType.ts index b8d42c9..8e468f9 100644 --- a/src/market/acquisition/AcquiredType.ts +++ b/src/market/acquisition/AcquiredType.ts @@ -7,4 +7,7 @@ export type AcquiredType = Omit & { sell: number } -export const acquiredTypesToSorted = (array: T[], reverse?: boolean) => array.toSorted((a, b) => reverse ? b.date.getTime() - a.date.getTime() : a.date.getTime() - b.date.getTime()) \ No newline at end of file +export const acquiredTypesToSorted = (array: T[], reverse?: boolean) => array.toSorted((a, b) => reverse ? b.date.getTime() - a.date.getTime() : a.date.getTime() - b.date.getTime()) + +export const toEveDatetimeInput = (date: Date) => date.toISOString().slice(0, 16) +export const fromEveDatetimeInput = (value: string) => new Date(`${value}Z`) \ No newline at end of file diff --git a/src/market/acquisition/AcquisitionsPanel.vue b/src/market/acquisition/AcquisitionsPanel.vue index 25aae93..88a82de 100644 --- a/src/market/acquisition/AcquisitionsPanel.vue +++ b/src/market/acquisition/AcquisitionsPanel.vue @@ -10,6 +10,7 @@ import SellModal from './SellModal.vue'; interface Props { items: RawAcquiredType[]; ignoredColums?: string[] | string; + ledgerId?: string; } const props = defineProps(); @@ -44,7 +45,7 @@ watch(() => props.items, async itms => {