feat(#47): Cash Flow / Margin toggle on the ledger Statistics profit chart
This commit is contained in:
@@ -359,6 +359,23 @@ paths:
|
||||
description: The link is seeded; follow with a full-page nav to /oauth2/authorization/esi
|
||||
"401":
|
||||
description: Missing or expired access token
|
||||
/balances/rebuild:
|
||||
post:
|
||||
tags:
|
||||
- balance-rebuild-admin-controller
|
||||
operationId: rebuild
|
||||
parameters:
|
||||
- name: ledgerIds
|
||||
in: query
|
||||
required: true
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
responses:
|
||||
"204":
|
||||
description: No Content
|
||||
/activity/consume:
|
||||
post:
|
||||
tags:
|
||||
@@ -405,6 +422,15 @@ paths:
|
||||
- activity
|
||||
summary: Process new activities for the authenticated user's characters
|
||||
operationId: processNewActivities
|
||||
parameters:
|
||||
- name: from
|
||||
in: query
|
||||
description: Reprocess by walking the processed tail back to this UTC datetime
|
||||
(ISO-8601); omit to only process new activities
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
format: date-time
|
||||
responses:
|
||||
"202":
|
||||
description: Processing started in the background
|
||||
@@ -932,6 +958,34 @@ paths:
|
||||
description: The ledger is the system ledger or a combined ledger
|
||||
"404":
|
||||
description: No ledger with this id
|
||||
/ledgers/{ledgerId}/margin:
|
||||
get:
|
||||
tags:
|
||||
- transaction
|
||||
summary: Get the daily FIFO-realized profit series for a single ledger
|
||||
operationId: marginPerDayInLedger
|
||||
parameters:
|
||||
- name: ledgerId
|
||||
in: path
|
||||
description: Id of the ledger
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
responses:
|
||||
"200":
|
||||
description: "Daily realized profit for the ledger, ascending by date, only\
|
||||
\ for days with a sale"
|
||||
content:
|
||||
'*/*':
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/DailyProfitResponse"
|
||||
"400":
|
||||
description: The ledger is the system ledger or a combined ledger
|
||||
"404":
|
||||
description: No ledger with this id
|
||||
/ledgers/{ledgerId}/balance:
|
||||
get:
|
||||
tags:
|
||||
|
||||
+184
-7
@@ -1012,10 +1012,11 @@ export const ActivityApiAxiosParamCreator = function (configuration?: Configurat
|
||||
/**
|
||||
*
|
||||
* @summary Process new activities for the authenticated user\'s characters
|
||||
* @param {string} [from] Reprocess by walking the processed tail back to this UTC datetime (ISO-8601); omit to only process new activities
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
processNewActivities: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
processNewActivities: async (from?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
const localVarPath = `/activities/process`;
|
||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
||||
@@ -1028,6 +1029,12 @@ export const ActivityApiAxiosParamCreator = function (configuration?: Configurat
|
||||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
if (from !== undefined) {
|
||||
localVarQueryParameter['from'] = (from as any instanceof Date) ?
|
||||
(from as any).toISOString() :
|
||||
from;
|
||||
}
|
||||
|
||||
|
||||
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
||||
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
||||
@@ -1106,11 +1113,12 @@ export const ActivityApiFp = function(configuration?: Configuration) {
|
||||
/**
|
||||
*
|
||||
* @summary Process new activities for the authenticated user\'s characters
|
||||
* @param {string} [from] Reprocess by walking the processed tail back to this UTC datetime (ISO-8601); omit to only process new activities
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async processNewActivities(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.processNewActivities(options);
|
||||
async processNewActivities(from?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.processNewActivities(from, options);
|
||||
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
|
||||
const localVarOperationServerBasePath = operationServerMap['ActivityApi.processNewActivities']?.[localVarOperationServerIndex]?.url;
|
||||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
||||
@@ -1159,11 +1167,12 @@ export const ActivityApiFactory = function (configuration?: Configuration, baseP
|
||||
/**
|
||||
*
|
||||
* @summary Process new activities for the authenticated user\'s characters
|
||||
* @param {string} [from] Reprocess by walking the processed tail back to this UTC datetime (ISO-8601); omit to only process new activities
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
processNewActivities(options?: RawAxiosRequestConfig): AxiosPromise<void> {
|
||||
return localVarFp.processNewActivities(options).then((request) => request(axios, basePath));
|
||||
processNewActivities(from?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {
|
||||
return localVarFp.processNewActivities(from, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
@@ -1206,11 +1215,12 @@ export class ActivityApi extends BaseAPI {
|
||||
/**
|
||||
*
|
||||
* @summary Process new activities for the authenticated user\'s characters
|
||||
* @param {string} [from] Reprocess by walking the processed tail back to this UTC datetime (ISO-8601); omit to only process new activities
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
public processNewActivities(options?: RawAxiosRequestConfig) {
|
||||
return ActivityApiFp(this.configuration).processNewActivities(options).then((request) => request(this.axios, this.basePath));
|
||||
public processNewActivities(from?: string, options?: RawAxiosRequestConfig) {
|
||||
return ActivityApiFp(this.configuration).processNewActivities(from, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1501,6 +1511,105 @@ export class AuthApi extends BaseAPI {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* BalanceRebuildAdminControllerApi - axios parameter creator
|
||||
*/
|
||||
export const BalanceRebuildAdminControllerApiAxiosParamCreator = function (configuration?: Configuration) {
|
||||
return {
|
||||
/**
|
||||
*
|
||||
* @param {Array<string>} ledgerIds
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
rebuild: async (ledgerIds: Array<string>, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'ledgerIds' is not null or undefined
|
||||
assertParamExists('rebuild', 'ledgerIds', ledgerIds)
|
||||
const localVarPath = `/balances/rebuild`;
|
||||
// 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;
|
||||
|
||||
if (ledgerIds) {
|
||||
localVarQueryParameter['ledgerIds'] = ledgerIds;
|
||||
}
|
||||
|
||||
|
||||
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
||||
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
||||
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
|
||||
|
||||
return {
|
||||
url: toPathString(localVarUrlObj),
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* BalanceRebuildAdminControllerApi - functional programming interface
|
||||
*/
|
||||
export const BalanceRebuildAdminControllerApiFp = function(configuration?: Configuration) {
|
||||
const localVarAxiosParamCreator = BalanceRebuildAdminControllerApiAxiosParamCreator(configuration)
|
||||
return {
|
||||
/**
|
||||
*
|
||||
* @param {Array<string>} ledgerIds
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async rebuild(ledgerIds: Array<string>, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.rebuild(ledgerIds, options);
|
||||
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
|
||||
const localVarOperationServerBasePath = operationServerMap['BalanceRebuildAdminControllerApi.rebuild']?.[localVarOperationServerIndex]?.url;
|
||||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* BalanceRebuildAdminControllerApi - factory interface
|
||||
*/
|
||||
export const BalanceRebuildAdminControllerApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {
|
||||
const localVarFp = BalanceRebuildAdminControllerApiFp(configuration)
|
||||
return {
|
||||
/**
|
||||
*
|
||||
* @param {Array<string>} ledgerIds
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
rebuild(ledgerIds: Array<string>, options?: RawAxiosRequestConfig): AxiosPromise<void> {
|
||||
return localVarFp.rebuild(ledgerIds, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* BalanceRebuildAdminControllerApi - object-oriented interface
|
||||
*/
|
||||
export class BalanceRebuildAdminControllerApi extends BaseAPI {
|
||||
/**
|
||||
*
|
||||
* @param {Array<string>} ledgerIds
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
public rebuild(ledgerIds: Array<string>, options?: RawAxiosRequestConfig) {
|
||||
return BalanceRebuildAdminControllerApiFp(this.configuration).rebuild(ledgerIds, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* CharacterApi - axios parameter creator
|
||||
*/
|
||||
@@ -3926,6 +4035,40 @@ export const TransactionApiAxiosParamCreator = function (configuration?: Configu
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary Get the daily FIFO-realized profit series for a single ledger
|
||||
* @param {string} ledgerId Id of the ledger
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
marginPerDayInLedger: async (ledgerId: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'ledgerId' is not null or undefined
|
||||
assertParamExists('marginPerDayInLedger', 'ledgerId', ledgerId)
|
||||
const localVarPath = `/ledgers/{ledgerId}/margin`
|
||||
.replace('{ledgerId}', encodeURIComponent(String(ledgerId)));
|
||||
// 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: 'GET', ...baseOptions, ...options};
|
||||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
localVarHeaderParameter['Accept'] = '*/*';
|
||||
|
||||
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
||||
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
||||
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
|
||||
|
||||
return {
|
||||
url: toPathString(localVarUrlObj),
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary Get the daily profit series for a single ledger
|
||||
@@ -3982,6 +4125,19 @@ export const TransactionApiFp = function(configuration?: Configuration) {
|
||||
const localVarOperationServerBasePath = operationServerMap['TransactionApi.finAllTransactionsInLedger']?.[localVarOperationServerIndex]?.url;
|
||||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary Get the daily FIFO-realized profit series for a single ledger
|
||||
* @param {string} ledgerId Id of the ledger
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async marginPerDayInLedger(ledgerId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<DailyProfitResponse>>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.marginPerDayInLedger(ledgerId, options);
|
||||
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
|
||||
const localVarOperationServerBasePath = operationServerMap['TransactionApi.marginPerDayInLedger']?.[localVarOperationServerIndex]?.url;
|
||||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary Get the daily profit series for a single ledger
|
||||
@@ -4014,6 +4170,16 @@ export const TransactionApiFactory = function (configuration?: Configuration, ba
|
||||
finAllTransactionsInLedger(ledgerId: string, options?: RawAxiosRequestConfig): AxiosPromise<Array<TransactionResponse>> {
|
||||
return localVarFp.finAllTransactionsInLedger(ledgerId, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary Get the daily FIFO-realized profit series for a single ledger
|
||||
* @param {string} ledgerId Id of the ledger
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
marginPerDayInLedger(ledgerId: string, options?: RawAxiosRequestConfig): AxiosPromise<Array<DailyProfitResponse>> {
|
||||
return localVarFp.marginPerDayInLedger(ledgerId, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary Get the daily profit series for a single ledger
|
||||
@@ -4042,6 +4208,17 @@ export class TransactionApi extends BaseAPI {
|
||||
return TransactionApiFp(this.configuration).finAllTransactionsInLedger(ledgerId, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @summary Get the daily FIFO-realized profit series for a single ledger
|
||||
* @param {string} ledgerId Id of the ledger
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
public marginPerDayInLedger(ledgerId: string, options?: RawAxiosRequestConfig) {
|
||||
return TransactionApiFp(this.configuration).marginPerDayInLedger(ledgerId, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @summary Get the daily profit series for a single ledger
|
||||
|
||||
@@ -34,12 +34,22 @@ ChartJS.register(
|
||||
|
||||
const {ledgerId} = useLedgerParam();
|
||||
|
||||
const ProfitModes = {
|
||||
CashFlow: 'CASH_FLOW',
|
||||
Margin: 'MARGIN',
|
||||
} as const;
|
||||
type ProfitMode = typeof ProfitModes[keyof typeof ProfitModes];
|
||||
|
||||
const mode = ref<ProfitMode>(ProfitModes.CashFlow);
|
||||
|
||||
const profits = useProcessedResource<DailyProfitResponse[]>(async () => {
|
||||
if (!ledgerId.value) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const {data} = await transactionApi.profitPerDayInLedger(ledgerId.value);
|
||||
const {data} = mode.value === ProfitModes.Margin
|
||||
? await transactionApi.marginPerDayInLedger(ledgerId.value)
|
||||
: await transactionApi.profitPerDayInLedger(ledgerId.value);
|
||||
|
||||
return data;
|
||||
}, []);
|
||||
@@ -131,6 +141,15 @@ const chartOptions = computed<ChartOptions<'bar' | 'line'>>(() => ({
|
||||
|
||||
<template>
|
||||
<div class="mt-4">
|
||||
<div class="flex justify-center mb-4">
|
||||
<div class="flex bg-slate-600 rounded-s-md p-1">
|
||||
<button class="switch" :class="{active: mode === ProfitModes.CashFlow}" @click="mode = ProfitModes.CashFlow">Cash Flow</button>
|
||||
</div>
|
||||
<div class="switch flex bg-slate-600 rounded-e-md p-1">
|
||||
<button class="switch" :class="{active: mode === ProfitModes.Margin}" @click="mode = ProfitModes.Margin">Margin</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end mb-4">
|
||||
<span class="mr-2">Total profit:</span>
|
||||
<IskLabel :amount="total" />
|
||||
@@ -153,3 +172,14 @@ const chartOptions = computed<ChartOptions<'bar' | 'line'>>(() => ({
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/style.css";
|
||||
|
||||
button.switch {
|
||||
@apply flex items-center px-4 rounded-md bg-slate-600;
|
||||
&.active {
|
||||
@apply bg-emerald-500;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user