From 32e1f16b4889711df4f4d843e7429e8ad7723035 Mon Sep 17 00:00:00 2001 From: NickolaiYurchenko Date: Wed, 1 Jul 2020 19:34:01 +0300 Subject: [PATCH] web/storagenode: current month held amount for all satellites Change-Id: I716a2695e5da19bfbec55d03e96bde0d2faa5ced --- .../components/payments/EstimationArea.vue | 10 ++- .../src/app/store/modules/payout.ts | 11 +++ web/storagenode/src/app/types/payout.ts | 34 ++++++++ web/storagenode/src/app/views/PayoutArea.vue | 6 ++ web/storagenode/src/storagenode/api/payout.ts | 43 ++++++++++ .../tests/unit/store/payout.spec.ts | 80 +++++++++++++++++++ 6 files changed, 180 insertions(+), 4 deletions(-) diff --git a/web/storagenode/src/app/components/payments/EstimationArea.vue b/web/storagenode/src/app/components/payments/EstimationArea.vue index 9733061fc..870aed9c3 100644 --- a/web/storagenode/src/app/components/payments/EstimationArea.vue +++ b/web/storagenode/src/app/components/payments/EstimationArea.vue @@ -80,7 +80,7 @@

{{ grossTotal | centsToDollars }}

-
+

Held back

-{{ held | centsToDollars }}

@@ -210,7 +210,7 @@ export default class EstimationArea extends Vue { */ public get totalPayout(): number { if (this.isCurrentPeriod) { - return this.isSatelliteSelected ? this.grossTotal - this.held : this.grossTotal; + return this.grossTotal - this.held; } return this.heldInfo.paid; @@ -333,10 +333,12 @@ export default class EstimationArea extends Vue { } /** - * Returns current month held amount based on currend day of month. + * Returns current month held amount based on current day of month. */ private currentMonthHeld(): number { - return this.grossTotal * this.$store.state.payoutModule.heldPercentage / 100; + return this.isSatelliteSelected ? + this.grossTotal * this.$store.state.payoutModule.heldPercentage / 100 : + this.$store.state.payoutModule.estimation.currentMonth.held; } } diff --git a/web/storagenode/src/app/store/modules/payout.ts b/web/storagenode/src/app/store/modules/payout.ts index beb98f4ce..450c80b2f 100644 --- a/web/storagenode/src/app/store/modules/payout.ts +++ b/web/storagenode/src/app/store/modules/payout.ts @@ -2,6 +2,7 @@ // See LICENSE for copying information. import { + EstimatedPayout, HeldHistory, HeldInfo, PaymentInfoParameters, @@ -20,6 +21,7 @@ export const PAYOUT_MUTATIONS = { SET_TOTAL: 'SET_TOTAL', SET_HELD_PERCENT: 'SET_HELD_PERCENT', SET_HELD_HISTORY: 'SET_HELD_HISTORY', + SET_ESTIMATION: 'SET_ESTIMATION', SET_PERIODS: 'SET_PERIODS', }; @@ -28,6 +30,7 @@ export const PAYOUT_ACTIONS = { SET_PERIODS_RANGE: 'SET_PERIODS_RANGE', GET_TOTAL: 'GET_TOTAL', GET_HELD_HISTORY: 'GET_HELD_HISTORY', + GET_ESTIMATION: 'GET_ESTIMATION', GET_PERIODS: 'GET_PERIODS', }; @@ -61,6 +64,9 @@ export function makePayoutModule(api: PayoutApi) { [PAYOUT_MUTATIONS.SET_HELD_HISTORY](state: PayoutState, heldHistory: HeldHistory): void { state.heldHistory = heldHistory; }, + [PAYOUT_MUTATIONS.SET_ESTIMATION](state: PayoutState, estimatedInfo: EstimatedPayout): void { + state.estimation = estimatedInfo; + }, [PAYOUT_MUTATIONS.SET_PERIODS](state: PayoutState, periods: PayoutPeriod[]): void { state.payoutPeriods = periods; }, @@ -121,6 +127,11 @@ export function makePayoutModule(api: PayoutApi) { commit(PAYOUT_MUTATIONS.SET_PERIODS, periods); }, + [PAYOUT_ACTIONS.GET_ESTIMATION]: async function ({commit}: any): Promise { + const estimatedInfo = await api.getEstimatedInfo(); + + commit(PAYOUT_MUTATIONS.SET_ESTIMATION, estimatedInfo); + }, }, }; } diff --git a/web/storagenode/src/app/types/payout.ts b/web/storagenode/src/app/types/payout.ts index fb3e0a890..33ed2d65e 100644 --- a/web/storagenode/src/app/types/payout.ts +++ b/web/storagenode/src/app/types/payout.ts @@ -95,6 +95,7 @@ export class PayoutState { public heldPercentage: number = 0, public payoutPeriods: PayoutPeriod[] = [], public heldHistory: HeldHistory = new HeldHistory(), + public estimation: EstimatedPayout = new EstimatedPayout(), ) {} } @@ -131,6 +132,12 @@ export interface PayoutApi { * @throws Error */ getHeldHistory(): Promise; + + /** + * Fetch estimated payout information. + * @throws Error + */ + getEstimatedInfo(): Promise; } /** @@ -156,3 +163,30 @@ export class HeldHistoryMonthlyBreakdownItem { public fourthPeriod: number = 0, ) {} } + +/** + * Contains estimated payout information for current and last periods. + */ +export class EstimatedPayout { + public constructor( + public currentMonth: PreviousMonthEstimatedPayout = new PreviousMonthEstimatedPayout(), + public previousMonth: PreviousMonthEstimatedPayout = new PreviousMonthEstimatedPayout(), + ) {} +} + +/** + * Contains last month estimated payout information. + */ +export class PreviousMonthEstimatedPayout { + public constructor( + public egressBandwidth: number = 0, + public egressBandwidthPayout: number = 0, + public egressRepairAudit: number = 0, + public egressRepairAuditPayout: number = 0, + public diskSpace: number = 0, + public diskSpacePayout: number = 0, + public heldRate: number = 0, + public payout: number = 0, + public held: number = 0, + ) {} +} diff --git a/web/storagenode/src/app/views/PayoutArea.vue b/web/storagenode/src/app/views/PayoutArea.vue index fc1ccf3e9..633856375 100644 --- a/web/storagenode/src/app/views/PayoutArea.vue +++ b/web/storagenode/src/app/views/PayoutArea.vue @@ -85,6 +85,12 @@ export default class PayoutArea extends Vue { console.error(error); } + try { + await this.$store.dispatch(PAYOUT_ACTIONS.GET_ESTIMATION); + } catch (error) { + console.error(error); + } + try { await this.$store.dispatch(PAYOUT_ACTIONS.GET_TOTAL); } catch (error) { diff --git a/web/storagenode/src/storagenode/api/payout.ts b/web/storagenode/src/storagenode/api/payout.ts index 1be301ac7..1e389f010 100644 --- a/web/storagenode/src/storagenode/api/payout.ts +++ b/web/storagenode/src/storagenode/api/payout.ts @@ -2,11 +2,13 @@ // See LICENSE for copying information. import { + EstimatedPayout, HeldHistory, HeldHistoryMonthlyBreakdownItem, HeldInfo, PaymentInfoParameters, PayoutApi, + PreviousMonthEstimatedPayout, PayoutPeriod, TotalPayoutInfo, } from '@/app/types/payout'; @@ -166,6 +168,47 @@ export class PayoutHttpApi implements PayoutApi { return new HeldHistory(monthlyBreakdown); } + /** + * Fetch estimated payout information. + * + * @returns estimated payout information + * @throws Error + */ + public async getEstimatedInfo(): Promise { + const response = await this.client.get('/api/sno/estimated-payout/'); + + if (!response.ok) { + throw new Error('can not get estimated payout information'); + } + + const data: any = await response.json() || []; + + return new EstimatedPayout( + new PreviousMonthEstimatedPayout( + data.currentMonth.egressBandwidth, + data.currentMonth.egressBandwidthPayout, + data.currentMonth.egressRepairAudit, + data.currentMonth.egressRepairAuditPayout, + data.currentMonth.diskSpace, + data.currentMonth.diskSpacePayout, + data.currentMonth.heldRate, + data.currentMonth.payout, + data.currentMonth.held, + ), + new PreviousMonthEstimatedPayout( + data.previousMonth.egressBandwidth, + data.previousMonth.egressBandwidthPayout, + data.previousMonth.egressRepairAudit, + data.previousMonth.egressRepairAuditPayout, + data.previousMonth.diskSpace, + data.previousMonth.diskSpacePayout, + data.previousMonth.heldRate, + data.previousMonth.payout, + data.previousMonth.held, + ), + ); + } + /** * Fetch total payout information depends on month. * diff --git a/web/storagenode/tests/unit/store/payout.spec.ts b/web/storagenode/tests/unit/store/payout.spec.ts index 6dd57a5b5..f51d11f1e 100644 --- a/web/storagenode/tests/unit/store/payout.spec.ts +++ b/web/storagenode/tests/unit/store/payout.spec.ts @@ -6,11 +6,13 @@ import Vuex from 'vuex'; import { makeNodeModule } from '@/app/store/modules/node'; import { makePayoutModule, PAYOUT_ACTIONS, PAYOUT_MUTATIONS } from '@/app/store/modules/payout'; import { + EstimatedPayout, HeldHistory, HeldHistoryMonthlyBreakdownItem, HeldInfo, PayoutInfoRange, PayoutPeriod, + PreviousMonthEstimatedPayout, TotalPayoutInfo, } from '@/app/types/payout'; import { getHeldPercentage, getMonthsBeforeNow } from '@/app/utils/payout'; @@ -90,6 +92,38 @@ describe('mutations', (): void => { expect(state.payoutModule.heldHistory.monthlyBreakdown[1].satelliteName).toBe(testHeldHistory.monthlyBreakdown[1].satelliteName); }); + it('sets estimated payout information', (): void => { + const estimatedPayout = new EstimatedPayout( + new PreviousMonthEstimatedPayout( + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + ), + new PreviousMonthEstimatedPayout( + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + ), + ); + + store.commit(PAYOUT_MUTATIONS.SET_ESTIMATION, estimatedPayout); + + expect(state.payoutModule.estimation.currentMonth.payout).toBe(8); + expect(state.payoutModule.estimation.previousMonth.heldRate).toBe(16); + }); + it('sets available periods', (): void => { const firstExpectedPeriod = '2020-04'; const secondExpectedPeriod = '1999-11'; @@ -243,6 +277,52 @@ describe('actions', () => { expect(state.payoutModule.heldHistory.monthlyBreakdown[1].satelliteName).toBe('name2'); } }); + + it('get estimated payout information throws an error when api call fails', async (): Promise => { + jest.spyOn(payoutApi, 'getEstimatedInfo').mockImplementation(() => { throw new Error(); }); + + try { + await store.dispatch(PAYOUT_ACTIONS.GET_ESTIMATION); + expect(true).toBe(false); + } catch (error) { + expect(state.payoutModule.estimation.currentMonth.held).toBe(9); + expect(state.payoutModule.estimation.previousMonth.diskSpace).toBe(14); + } + }); + + it('success get estimated payout information', async (): Promise => { + jest.spyOn(payoutApi, 'getEstimatedInfo').mockReturnValue( + Promise.resolve(new EstimatedPayout( + new PreviousMonthEstimatedPayout( + 1, + 2, + 300, + 4, + 5, + 6, + 7, + 8, + 9, + ), + new PreviousMonthEstimatedPayout( + 10, + 11, + 12, + 13, + 700, + 15, + 16, + 17, + 18, + ), + )), + ); + + await store.dispatch(PAYOUT_ACTIONS.GET_ESTIMATION); + + expect(state.payoutModule.estimation.currentMonth.egressRepairAudit).toBe(300); + expect(state.payoutModule.estimation.previousMonth.diskSpace).toBe(700); + }); }); describe('utils functions', (): void => {