web/storagenode: frontend refactoring
WHAT: separation of domain and presentation entities WHY: to have ability to easily reuse logic Change-Id: I48f7d1831c217dec999ff1b678034bb2c10cfbaa
This commit is contained in:
parent
7db5794c16
commit
9a627b22e8
1621
web/storagenode/package-lock.json
generated
1621
web/storagenode/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -30,7 +30,7 @@
|
||||
"@vue/cli-service": "4.1.1",
|
||||
"@vue/test-utils": "1.0.0-beta.30",
|
||||
"babel-core": "7.0.0-bridge.0",
|
||||
"compression-webpack-plugin": "3.0.1",
|
||||
"compression-webpack-plugin": "6.0.0",
|
||||
"core-js": "3.6.5",
|
||||
"jest-fetch-mock": "3.0.0",
|
||||
"node-sass": "4.14.1",
|
||||
|
@ -530,6 +530,7 @@ export default class SNOContentFilling extends Vue {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
text-decoration: none;
|
||||
|
||||
&__text {
|
||||
font-size: 16px;
|
||||
|
@ -184,7 +184,7 @@ export default class SNOHeader extends Vue {
|
||||
await this.$store.dispatch(APPSTATE_ACTIONS.SET_LOADING, false);
|
||||
|
||||
try {
|
||||
await this.$store.dispatch(PAYOUT_ACTIONS.GET_HELD_INFO, selectedSatellite);
|
||||
await this.$store.dispatch(PAYOUT_ACTIONS.GET_PAYOUT_INFO, selectedSatellite);
|
||||
await this.$store.dispatch(PAYOUT_ACTIONS.GET_TOTAL);
|
||||
} catch (error) {
|
||||
console.error(error.message);
|
||||
|
@ -31,8 +31,9 @@ import SuspensionIcon from '@/../static/images/suspend.svg';
|
||||
import { APPSTATE_ACTIONS } from '@/app/store/modules/appState';
|
||||
import { NODE_ACTIONS } from '@/app/store/modules/node';
|
||||
import { PAYOUT_ACTIONS } from '@/app/store/modules/payout';
|
||||
import { PayoutInfoRange, PayoutPeriod } from '@/app/types/payout';
|
||||
import { PayoutInfoRange } from '@/app/types/payout';
|
||||
import { SatelliteInfo } from '@/storagenode/dashboard';
|
||||
import { PayoutPeriod } from '@/storagenode/payouts/payouts';
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
|
@ -37,11 +37,11 @@ import SingleInfo from '@/app/components/payments/SingleInfo.vue';
|
||||
})
|
||||
export default class TotalPayoutArea extends Vue {
|
||||
public get totalEarnings(): number {
|
||||
return this.$store.state.payoutModule.totalEarnings;
|
||||
return this.$store.state.payoutModule.totalHeldAndPaid.paid;
|
||||
}
|
||||
|
||||
public get totalHeld(): number {
|
||||
return this.$store.state.payoutModule.totalHeldAmount;
|
||||
return this.$store.state.payoutModule.totalHeldAndPaid.held;
|
||||
}
|
||||
|
||||
public get currentEarnings(): number {
|
||||
|
@ -5,8 +5,8 @@
|
||||
<div class="notification-popup-container">
|
||||
<div class="notification-popup-container__header">
|
||||
<p class="notification-popup-container__header__title">Notifications</p>
|
||||
<router-link :to="notificationsPath">
|
||||
<p class="notification-popup-container__header__link">See All</p>
|
||||
<router-link :to="notificationsPath" class="notification-popup-container__header__link">
|
||||
<p>See All</p>
|
||||
</router-link>
|
||||
</div>
|
||||
<div
|
||||
@ -92,6 +92,7 @@ export default class NotificationsPopup extends Vue {
|
||||
font-size: 14px;
|
||||
color: var(--navigation-link-color);
|
||||
margin-right: 20px;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,8 @@ import { Component, Vue } from 'vue-property-decorator';
|
||||
import BlueHideIcon from '@/../static/images/common/BlueMinus.svg';
|
||||
import BlueExpandIcon from '@/../static/images/common/BluePlus.svg';
|
||||
|
||||
import { SatelliteHeldHistory } from '@/storagenode/payouts/payouts';
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
BlueExpandIcon,
|
||||
@ -14,6 +16,13 @@ import BlueExpandIcon from '@/../static/images/common/BluePlus.svg';
|
||||
},
|
||||
})
|
||||
export default class BaseSmallHeldHistoryTable extends Vue {
|
||||
/**
|
||||
* Indicates if held info should be rendered.
|
||||
*/
|
||||
public get allSatellitesHeldHistory(): SatelliteHeldHistory[] {
|
||||
return this.$store.state.payoutModule.heldHistory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if held info should be rendered.
|
||||
*/
|
||||
|
@ -81,7 +81,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="estimation-table-container__held-area">
|
||||
<p class="estimation-table-container__held-area__text">Held back</p>
|
||||
<p class="estimation-table-container__held-area__text">Held Back</p>
|
||||
<p class="estimation-table-container__held-area__text">-{{ held | centsToDollars }}</p>
|
||||
</div>
|
||||
<div class="estimation-table-container__held-area" v-if="!isCurrentPeriod && disposed > 0">
|
||||
@ -104,9 +104,9 @@
|
||||
<p class="estimation-table-container__net-total-area__text">{{ totalPayout | centsToDollars }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="estimation-table-container__total-area" v-if="!isCurrentPeriod && !isLastPeriodWithoutPaystub && heldInfo.surgePercent">
|
||||
<div class="estimation-table-container__total-area" v-if="!isCurrentPeriod && !isLastPeriodWithoutPaystub && totalPaystubForPeriod.surgePercent">
|
||||
<p class="estimation-table-container__total-area__text">Total + Surge {{ surgePercent }}</p>
|
||||
<p class="estimation-table-container__total-area__text">{{ heldInfo.paid | centsToDollars }}</p>
|
||||
<p class="estimation-table-container__total-area__text">{{ totalPaystubForPeriod.paid | centsToDollars }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="no-data-container" v-else>
|
||||
@ -129,13 +129,11 @@ import {
|
||||
DISK_SPACE_PRICE_PER_TB, PAYOUT_ACTIONS,
|
||||
} from '@/app/store/modules/payout';
|
||||
import {
|
||||
EstimatedPayout,
|
||||
HeldInfo,
|
||||
monthNames,
|
||||
PayoutInfoRange,
|
||||
PayoutPeriod,
|
||||
} from '@/app/types/payout';
|
||||
import { formatBytes, TB } from '@/app/utils/converter';
|
||||
import { formatBytes } from '@/app/utils/converter';
|
||||
import { EstimatedPayout, PayoutPeriod, TotalPaystubForPeriod } from '@/storagenode/payouts/payouts';
|
||||
|
||||
/**
|
||||
* Describes table row data item.
|
||||
@ -213,7 +211,7 @@ export default class EstimationArea extends Vue {
|
||||
* Returns surge percent if single month selected.
|
||||
*/
|
||||
public get surgePercent(): string {
|
||||
return !this.$store.state.payoutModule.periodRange.start ? `(${this.heldInfo.surgePercent}%)` : '';
|
||||
return !this.$store.state.payoutModule.periodRange.start ? `(${this.totalPaystubForPeriod.surgePercent}%)` : '';
|
||||
}
|
||||
|
||||
/**
|
||||
@ -224,10 +222,10 @@ export default class EstimationArea extends Vue {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns held info from store.
|
||||
* Returns payout info from store.
|
||||
*/
|
||||
public get heldInfo(): HeldInfo {
|
||||
return this.$store.state.payoutModule.heldInfo;
|
||||
public get totalPaystubForPeriod(): TotalPaystubForPeriod {
|
||||
return this.$store.state.payoutModule.totalPaystubForPeriod;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -242,7 +240,7 @@ export default class EstimationArea extends Vue {
|
||||
*/
|
||||
public get held(): number {
|
||||
if (!this.isCurrentPeriod && !this.isLastPeriodWithoutPaystub) {
|
||||
return this.heldInfo.held;
|
||||
return this.totalPaystubForPeriod.held;
|
||||
}
|
||||
|
||||
return this.estimatedHeld();
|
||||
@ -252,7 +250,7 @@ export default class EstimationArea extends Vue {
|
||||
* Returns calculated or stored returned held amount.
|
||||
*/
|
||||
public get disposed(): number {
|
||||
return this.heldInfo.disposed;
|
||||
return this.totalPaystubForPeriod.disposed;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -260,7 +258,7 @@ export default class EstimationArea extends Vue {
|
||||
*/
|
||||
public get totalPayout(): number {
|
||||
if (!this.isCurrentPeriod && !this.isLastPeriodWithoutPaystub) {
|
||||
return this.heldInfo.paid;
|
||||
return this.totalPaystubForPeriod.paid;
|
||||
}
|
||||
|
||||
return this.grossTotal;
|
||||
@ -281,7 +279,7 @@ export default class EstimationArea extends Vue {
|
||||
return formatBytes(this.currentDiskSpace);
|
||||
}
|
||||
|
||||
return formatBytes(this.heldInfo.usageAtRest);
|
||||
return formatBytes(this.totalPaystubForPeriod.usageAtRest);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -292,7 +290,7 @@ export default class EstimationArea extends Vue {
|
||||
return formatBytes((this.currentBandwidthAuditAndRepair + this.currentBandwidthDownload));
|
||||
}
|
||||
|
||||
const bandwidthSum = this.heldInfo.usageGet + this.heldInfo.usageGetRepair + this.heldInfo.usageGetAudit;
|
||||
const bandwidthSum = this.totalPaystubForPeriod.usageGet + this.totalPaystubForPeriod.usageGetRepair + this.totalPaystubForPeriod.usageGetAudit;
|
||||
|
||||
return formatBytes(bandwidthSum);
|
||||
}
|
||||
@ -324,9 +322,9 @@ export default class EstimationArea extends Vue {
|
||||
public get tableData(): EstimationTableRow[] {
|
||||
if (!this.isCurrentPeriod && !this.isLastPeriodWithoutPaystub) {
|
||||
return [
|
||||
new EstimationTableRow('Download', 'Egress', `$${BANDWIDTH_DOWNLOAD_PRICE_PER_TB / 100} / TB`, '--', formatBytes(this.heldInfo.usageGet), this.heldInfo.compGet),
|
||||
new EstimationTableRow('Repair & Audit', 'Egress', `$${BANDWIDTH_REPAIR_PRICE_PER_TB / 100} / TB`, '--', formatBytes(this.heldInfo.usageGetRepair + this.heldInfo.usageGetAudit), this.heldInfo.compGetRepair + this.heldInfo.compGetAudit),
|
||||
new EstimationTableRow('Disk Average Month', 'Storage', `$${DISK_SPACE_PRICE_PER_TB / 100} / TBm`, formatBytes(this.heldInfo.usageAtRest) + 'm', '--', this.heldInfo.compAtRest),
|
||||
new EstimationTableRow('Download', 'Egress', `$${BANDWIDTH_DOWNLOAD_PRICE_PER_TB / 100} / TB`, '--', formatBytes(this.totalPaystubForPeriod.usageGet), this.totalPaystubForPeriod.compGet),
|
||||
new EstimationTableRow('Repair & Audit', 'Egress', `$${BANDWIDTH_REPAIR_PRICE_PER_TB / 100} / TB`, '--', formatBytes(this.totalPaystubForPeriod.usageGetRepair + this.totalPaystubForPeriod.usageGetAudit), this.totalPaystubForPeriod.compGetRepair + this.totalPaystubForPeriod.compGetAudit),
|
||||
new EstimationTableRow('Disk Average Month', 'Storage', `$${DISK_SPACE_PRICE_PER_TB / 100} / TBm`, formatBytes(this.totalPaystubForPeriod.usageAtRest) + 'm', '--', this.totalPaystubForPeriod.compAtRest),
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -18,10 +18,10 @@
|
||||
<p class="held-history-table-container--large__labels-area__text">Held Returned</p>
|
||||
</div>
|
||||
</div>
|
||||
<div v-for="item in allStats" class="held-history-table-container--large__info-area" :key="item.satelliteID">
|
||||
<div v-for="item in allSatellitesHeldHistory" class="held-history-table-container--large__info-area" :key="item.satelliteID">
|
||||
<div class="justify-start column-1">
|
||||
<p class="held-history-table-container--large__info-area__text">{{ item.satelliteName }}</p>
|
||||
<p class="held-history-table-container--large__info-area__months">{{ item.age }} month</p>
|
||||
<p class="held-history-table-container--large__info-area__months">{{ item.monthsWithNode }} month</p>
|
||||
</div>
|
||||
<div class="column justify-end column-2">
|
||||
<p class="held-history-table-container--large__info-area__text">{{ item.joinedAt.toISOString().split('T')[0] }}</p>
|
||||
@ -36,7 +36,7 @@
|
||||
</div>
|
||||
<div class="held-history-table-container--small">
|
||||
<HeldHistoryAllStatsTableItemSmall
|
||||
v-for="item in allStats"
|
||||
v-for="item in allSatellitesHeldHistory"
|
||||
:held-history-item="item"
|
||||
:key="item.satelliteID"
|
||||
/>
|
||||
@ -50,7 +50,7 @@ import { Component } from 'vue-property-decorator';
|
||||
import BaseHeldHistoryTable from '@/app/components/payments/BaseHeldHistoryTable.vue';
|
||||
import HeldHistoryAllStatsTableItemSmall from '@/app/components/payments/HeldHistoryAllStatsTableItemSmall.vue';
|
||||
|
||||
import { HeldHistoryAllStatItem } from '@/app/types/payout';
|
||||
import { SatelliteHeldHistory } from '@/storagenode/payouts/payouts';
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
@ -61,8 +61,8 @@ export default class HeldHistoryAllStatsTable extends BaseHeldHistoryTable {
|
||||
/**
|
||||
* Returns list of satellite held history items by periods from store.
|
||||
*/
|
||||
public get allStats(): HeldHistoryAllStatItem[] {
|
||||
return this.$store.state.payoutModule.heldHistory.allStats;
|
||||
public get allSatellitesHeldHistory(): SatelliteHeldHistory[] {
|
||||
return this.$store.state.payoutModule.heldHistory;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<div class="held-history-table-container--small__item__satellite-info">
|
||||
<div>
|
||||
<p class="held-history-table-container--small__item__satellite-info__name">{{ heldHistoryItem.satelliteName }}</p>
|
||||
<p class="held-history-table-container--small__item__satellite-info__months">{{ heldHistoryItem.age }} month</p>
|
||||
<p class="held-history-table-container--small__item__satellite-info__months">{{ heldHistoryItem.monthsWithNode }} month</p>
|
||||
</div>
|
||||
<div class="held-history-table-container--small__item__satellite-info__button">
|
||||
<div class="icon hide" @click="hide" v-if="isExpanded">
|
||||
@ -41,11 +41,11 @@ import { Component, Prop } from 'vue-property-decorator';
|
||||
|
||||
import BaseSmallHeldHistoryTable from '@/app/components/payments/BaseSmallHeldHistoryTable.vue';
|
||||
|
||||
import { HeldHistoryAllStatItem } from '@/app/types/payout';
|
||||
import { SatelliteHeldHistory } from '@/storagenode/payouts/payouts';
|
||||
|
||||
@Component
|
||||
export default class HeldHistoryAllStatsTableSmall extends BaseSmallHeldHistoryTable {
|
||||
@Prop({default: () => new HeldHistoryAllStatItem()})
|
||||
public readonly heldHistoryItem: HeldHistoryAllStatItem;
|
||||
@Prop({default: () => new SatelliteHeldHistory()})
|
||||
public readonly heldHistoryItem: SatelliteHeldHistory;
|
||||
}
|
||||
</script>
|
||||
|
@ -18,10 +18,10 @@
|
||||
<p class="held-history-table-container--large__labels-area__text">Month 7-9</p>
|
||||
</div>
|
||||
</div>
|
||||
<div v-for="item in monthlyBreakdown" class="held-history-table-container--large__info-area" :key="item.satelliteID">
|
||||
<div v-for="item in allSatellitesHeldHistory" class="held-history-table-container--large__info-area" :key="item.satelliteID">
|
||||
<div class="justify-start column-1">
|
||||
<p class="held-history-table-container--large__info-area__text">{{ item.satelliteName }}</p>
|
||||
<p class="held-history-table-container--large__info-area__months">{{ item.age }} month</p>
|
||||
<p class="held-history-table-container--large__info-area__months">{{ item.monthsWithNode }} month</p>
|
||||
</div>
|
||||
<div class="column justify-end column-2">
|
||||
<p class="held-history-table-container--large__info-area__text">{{ item.firstPeriod | centsToDollars }}</p>
|
||||
@ -36,7 +36,7 @@
|
||||
</div>
|
||||
<div class="held-history-table-container--small">
|
||||
<HeldHistoryMonthlyBreakdownTableItemSmall
|
||||
v-for="item in monthlyBreakdown"
|
||||
v-for="item in allSatellitesHeldHistory"
|
||||
:held-history-item="item"
|
||||
:key="item.satelliteID"
|
||||
/>
|
||||
@ -50,7 +50,7 @@ import { Component, Vue } from 'vue-property-decorator';
|
||||
import BaseHeldHistoryTable from '@/app/components/payments/BaseHeldHistoryTable.vue';
|
||||
import HeldHistoryMonthlyBreakdownTableItemSmall from '@/app/components/payments/HeldHistoryMonthlyBreakdownTableItemSmall.vue';
|
||||
|
||||
import { HeldHistoryMonthlyBreakdownItem } from '@/app/types/payout';
|
||||
import { SatelliteHeldHistory } from '@/storagenode/payouts/payouts';
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
@ -61,8 +61,8 @@ export default class HeldHistoryMonthlyBreakdownTable extends BaseHeldHistoryTab
|
||||
/**
|
||||
* Returns list of satellite held history items by periods from store.
|
||||
*/
|
||||
public get monthlyBreakdown(): HeldHistoryMonthlyBreakdownItem[] {
|
||||
return this.$store.state.payoutModule.heldHistory.monthlyBreakdown;
|
||||
public get allSatellitesHeldHistory(): SatelliteHeldHistory[] {
|
||||
return this.$store.state.payoutModule.heldHistory;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<div class="held-history-table-container--small__item__satellite-info">
|
||||
<div>
|
||||
<p class="held-history-table-container--small__item__satellite-info__name">{{ heldHistoryItem.satelliteName }}</p>
|
||||
<p class="held-history-table-container--small__item__satellite-info__months">{{ heldHistoryItem.age }} month</p>
|
||||
<p class="held-history-table-container--small__item__satellite-info__months">{{ heldHistoryItem.monthsWithNode }} month</p>
|
||||
</div>
|
||||
<div class="held-history-table-container--small__item__satellite-info__button">
|
||||
<div class="icon hide" @click="hide" v-if="isExpanded">
|
||||
@ -41,11 +41,11 @@ import { Component, Prop } from 'vue-property-decorator';
|
||||
|
||||
import BaseSmallHeldHistoryTable from '@/app/components/payments/BaseSmallHeldHistoryTable.vue';
|
||||
|
||||
import { HeldHistoryMonthlyBreakdownItem } from '@/app/types/payout';
|
||||
import { SatelliteHeldHistory } from '@/storagenode/payouts/payouts';
|
||||
|
||||
@Component
|
||||
export default class HeldHistoryMonthlyBreakdownTableSmall extends BaseSmallHeldHistoryTable {
|
||||
@Prop({default: () => new HeldHistoryMonthlyBreakdownItem()})
|
||||
public readonly heldHistoryItem: HeldHistoryMonthlyBreakdownItem;
|
||||
@Prop({default: () => new SatelliteHeldHistory()})
|
||||
public readonly heldHistoryItem: SatelliteHeldHistory;
|
||||
}
|
||||
</script>
|
||||
|
@ -31,7 +31,7 @@ import PayoutHistoryPeriodDropdown from '@/app/components/payments/PayoutHistory
|
||||
import PayoutHistoryTableItem from '@/app/components/payments/PayoutHistoryTableItem.vue';
|
||||
|
||||
import { PAYOUT_ACTIONS } from '@/app/store/modules/payout';
|
||||
import { PayoutHistoryItem } from '@/app/types/payout';
|
||||
import { SatellitePayoutForPeriod } from '@/storagenode/payouts/payouts';
|
||||
|
||||
@Component ({
|
||||
components: {
|
||||
@ -40,7 +40,7 @@ import { PayoutHistoryItem } from '@/app/types/payout';
|
||||
},
|
||||
})
|
||||
export default class PayoutHistoryTable extends Vue {
|
||||
public get payoutHistory(): PayoutHistoryItem[] {
|
||||
public get payoutHistory(): SatellitePayoutForPeriod[] {
|
||||
return this.$store.state.payoutModule.payoutHistory;
|
||||
}
|
||||
|
||||
@ -62,7 +62,7 @@ export default class PayoutHistoryTable extends Vue {
|
||||
return;
|
||||
}
|
||||
|
||||
const lastPeriod = payoutPeriods[0];
|
||||
const lastPeriod = payoutPeriods[payoutPeriods.length - 1];
|
||||
await this.$store.dispatch(PAYOUT_ACTIONS.SET_PAYOUT_HISTORY_PERIOD, lastPeriod.period);
|
||||
|
||||
try {
|
||||
|
@ -81,7 +81,14 @@
|
||||
<div class="payout-history-item__expanded-area__right-area__divider"></div>
|
||||
<div class="payout-history-item__expanded-area__right-area__footer">
|
||||
<div class="payout-history-item__expanded-area__right-area__footer__transaction" v-if="historyItem.receipt">
|
||||
<a :href="historyItem.receipt" target="_blank" rel="noreferrer noopener">Transaction</a>
|
||||
<a
|
||||
class="payout-history-item__expanded-area__right-area__footer__transaction__link"
|
||||
:href="historyItem.receipt"
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
>
|
||||
Transaction
|
||||
</a>
|
||||
<ShareIcon class="payout-history-item__expanded-area__right-area__footer__transaction__icon" />
|
||||
</div>
|
||||
<p class="payout-history-item__expanded-area__right-area__footer__total">{{ historyItem.paid | centsToDollars }}</p>
|
||||
@ -100,7 +107,7 @@ import DisqualifyIcon from '@/../static/images/largeDisqualify.svg';
|
||||
import OKIcon from '@/../static/images/payments/OKIcon.svg';
|
||||
import ShareIcon from '@/../static/images/payments/Share.svg';
|
||||
|
||||
import { PayoutHistoryItem } from '@/app/types/payout';
|
||||
import { SatellitePayoutForPeriod } from '@/storagenode/payouts/payouts';
|
||||
|
||||
@Component ({
|
||||
components: {
|
||||
@ -111,8 +118,8 @@ import { PayoutHistoryItem } from '@/app/types/payout';
|
||||
},
|
||||
})
|
||||
export default class PayoutHistoryTableItem extends Vue {
|
||||
@Prop({default: () => new PayoutHistoryItem()})
|
||||
public readonly historyItem: PayoutHistoryItem;
|
||||
@Prop({default: () => new SatellitePayoutForPeriod()})
|
||||
public readonly historyItem: SatellitePayoutForPeriod;
|
||||
|
||||
/**
|
||||
* Indicates if payout info should be rendered.
|
||||
@ -291,18 +298,18 @@ export default class PayoutHistoryTableItem extends Vue {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
color: var(--link-color);
|
||||
color: var(--navigation-link-color);
|
||||
cursor: pointer;
|
||||
|
||||
a:visited {
|
||||
color: var(--link-color);
|
||||
color: var(--navigation-link-color);
|
||||
}
|
||||
|
||||
&__icon {
|
||||
margin-left: 7px;
|
||||
|
||||
path {
|
||||
stroke: var(--link-color);
|
||||
stroke: var(--navigation-link-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -44,9 +44,9 @@ import {
|
||||
MonthButton,
|
||||
monthNames,
|
||||
PayoutInfoRange,
|
||||
PayoutPeriod,
|
||||
StoredMonthsByYear,
|
||||
} from '@/app/types/payout';
|
||||
import { PayoutPeriod } from '@/storagenode/payouts/payouts';
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
@ -95,7 +95,7 @@ export default class PayoutPeriodCalendar extends Vue {
|
||||
);
|
||||
|
||||
try {
|
||||
await this.$store.dispatch(PAYOUT_ACTIONS.GET_HELD_INFO, this.$store.state.node.selectedSatellite.id);
|
||||
await this.$store.dispatch(PAYOUT_ACTIONS.GET_PAYOUT_INFO, this.$store.state.node.selectedSatellite.id);
|
||||
await this.$store.dispatch(APPSTATE_ACTIONS.SET_NO_PAYOUT_DATA, false);
|
||||
} catch (error) {
|
||||
const lastMonthDate = new Date();
|
||||
|
@ -9,12 +9,14 @@ import { makePayoutModule } from '@/app/store/modules/payout';
|
||||
import { NotificationsHttpApi } from '@/storagenode/api/notifications';
|
||||
import { PayoutHttpApi } from '@/storagenode/api/payout';
|
||||
import { SNOApi } from '@/storagenode/api/storagenode';
|
||||
import { PayoutService } from '@/storagenode/payouts/service';
|
||||
|
||||
import { appStateModule } from './modules/appState';
|
||||
import { makeNodeModule } from './modules/node';
|
||||
|
||||
const notificationsApi = new NotificationsHttpApi();
|
||||
const payoutApi = new PayoutHttpApi();
|
||||
const payoutService = new PayoutService(payoutApi);
|
||||
const nodeApi = new SNOApi();
|
||||
|
||||
Vue.use(Vuex);
|
||||
@ -27,7 +29,7 @@ export const store = new Vuex.Store({
|
||||
node: makeNodeModule(nodeApi),
|
||||
appStateModule,
|
||||
notificationsModule: makeNotificationsModule(notificationsApi),
|
||||
payoutModule: makePayoutModule(payoutApi),
|
||||
payoutModule: makePayoutModule(payoutApi, payoutService),
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -2,22 +2,24 @@
|
||||
// See LICENSE for copying information.
|
||||
|
||||
import {
|
||||
EstimatedPayout,
|
||||
HeldHistory,
|
||||
HeldInfo,
|
||||
PaymentInfoParameters,
|
||||
PayoutApi,
|
||||
PayoutHistoryItem,
|
||||
PayoutInfoRange,
|
||||
PayoutPeriod,
|
||||
PayoutState,
|
||||
TotalPayoutInfo,
|
||||
} from '@/app/types/payout';
|
||||
import { TB } from '@/app/utils/converter';
|
||||
import { getHeldPercentage } from '@/app/utils/payout';
|
||||
import {
|
||||
EstimatedPayout,
|
||||
PayoutApi,
|
||||
PayoutPeriod,
|
||||
SatelliteHeldHistory,
|
||||
SatellitePayoutForPeriod,
|
||||
TotalHeldAndPaid,
|
||||
TotalPaystubForPeriod,
|
||||
} from '@/storagenode/payouts/payouts';
|
||||
import { PayoutService } from '@/storagenode/payouts/service';
|
||||
|
||||
export const PAYOUT_MUTATIONS = {
|
||||
SET_HELD_INFO: 'SET_HELD_INFO',
|
||||
SET_PAYOUT_INFO: 'SET_PAYOUT_INFO',
|
||||
SET_RANGE: 'SET_RANGE',
|
||||
SET_TOTAL: 'SET_TOTAL',
|
||||
SET_HELD_PERCENT: 'SET_HELD_PERCENT',
|
||||
@ -29,7 +31,7 @@ export const PAYOUT_MUTATIONS = {
|
||||
};
|
||||
|
||||
export const PAYOUT_ACTIONS = {
|
||||
GET_HELD_INFO: 'GET_HELD_INFO',
|
||||
GET_PAYOUT_INFO: 'GET_PAYOUT_INFO',
|
||||
SET_PERIODS_RANGE: 'SET_PERIODS_RANGE',
|
||||
GET_TOTAL: 'GET_TOTAL',
|
||||
GET_HELD_HISTORY: 'GET_HELD_HISTORY',
|
||||
@ -39,6 +41,7 @@ export const PAYOUT_ACTIONS = {
|
||||
SET_PAYOUT_HISTORY_PERIOD: 'SET_PAYOUT_HISTORY_PERIOD',
|
||||
};
|
||||
|
||||
// TODO: move to config in storagenode/payouts
|
||||
export const BANDWIDTH_DOWNLOAD_PRICE_PER_TB = 2000;
|
||||
export const BANDWIDTH_REPAIR_PRICE_PER_TB = 1000;
|
||||
export const DISK_SPACE_PRICE_PER_TB = 150;
|
||||
@ -47,18 +50,18 @@ export const DISK_SPACE_PRICE_PER_TB = 150;
|
||||
* creates notifications module with all dependencies
|
||||
*
|
||||
* @param api - payments api
|
||||
* @param service - payments service
|
||||
*/
|
||||
export function makePayoutModule(api: PayoutApi) {
|
||||
export function makePayoutModule(api: PayoutApi, service: PayoutService) {
|
||||
return {
|
||||
state: new PayoutState(),
|
||||
mutations: {
|
||||
[PAYOUT_MUTATIONS.SET_HELD_INFO](state: PayoutState, heldInfo: HeldInfo): void {
|
||||
state.heldInfo = heldInfo;
|
||||
[PAYOUT_MUTATIONS.SET_PAYOUT_INFO](state: PayoutState, totalPaystubForPeriod: TotalPaystubForPeriod): void {
|
||||
state.totalPaystubForPeriod = totalPaystubForPeriod;
|
||||
},
|
||||
[PAYOUT_MUTATIONS.SET_TOTAL](state: PayoutState, totalPayoutInfo: TotalPayoutInfo): void {
|
||||
state.totalEarnings = totalPayoutInfo.totalEarnings;
|
||||
state.totalHeldAmount = totalPayoutInfo.totalHeldAmount;
|
||||
state.currentMonthEarnings = totalPayoutInfo.currentMonthEarnings;
|
||||
[PAYOUT_MUTATIONS.SET_TOTAL](state: PayoutState, totalHeldAndPaid: TotalHeldAndPaid): void {
|
||||
state.totalHeldAndPaid = totalHeldAndPaid;
|
||||
state.currentMonthEarnings = totalHeldAndPaid.currentMonthEarnings;
|
||||
},
|
||||
[PAYOUT_MUTATIONS.SET_RANGE](state: PayoutState, periodRange: PayoutInfoRange): void {
|
||||
state.periodRange = periodRange;
|
||||
@ -66,7 +69,7 @@ export function makePayoutModule(api: PayoutApi) {
|
||||
[PAYOUT_MUTATIONS.SET_HELD_PERCENT](state: PayoutState, heldPercentage: number): void {
|
||||
state.heldPercentage = heldPercentage;
|
||||
},
|
||||
[PAYOUT_MUTATIONS.SET_HELD_HISTORY](state: PayoutState, heldHistory: HeldHistory): void {
|
||||
[PAYOUT_MUTATIONS.SET_HELD_HISTORY](state: PayoutState, heldHistory: SatelliteHeldHistory[]): void {
|
||||
state.heldHistory = heldHistory;
|
||||
},
|
||||
[PAYOUT_MUTATIONS.SET_ESTIMATION](state: PayoutState, estimatedInfo: EstimatedPayout): void {
|
||||
@ -75,7 +78,7 @@ export function makePayoutModule(api: PayoutApi) {
|
||||
[PAYOUT_MUTATIONS.SET_PERIODS](state: PayoutState, periods: PayoutPeriod[]): void {
|
||||
state.payoutPeriods = periods;
|
||||
},
|
||||
[PAYOUT_MUTATIONS.SET_PAYOUT_HISTORY](state: PayoutState, payoutHistory: PayoutHistoryItem[]): void {
|
||||
[PAYOUT_MUTATIONS.SET_PAYOUT_HISTORY](state: PayoutState, payoutHistory: SatellitePayoutForPeriod[]): void {
|
||||
state.payoutHistory = payoutHistory;
|
||||
},
|
||||
[PAYOUT_MUTATIONS.SET_PAYOUT_HISTORY_PERIOD](state: PayoutState, period: string): void {
|
||||
@ -83,28 +86,24 @@ export function makePayoutModule(api: PayoutApi) {
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
[PAYOUT_ACTIONS.GET_HELD_INFO]: async function ({ commit, state, rootState }: any, satelliteId: string = ''): Promise<void> {
|
||||
const heldInfo = state.periodRange.start ? await api.getHeldInfoByPeriod(new PaymentInfoParameters(
|
||||
[PAYOUT_ACTIONS.GET_PAYOUT_INFO]: async function ({ commit, state, rootState }: any, satelliteId: string = ''): Promise<void> {
|
||||
const totalPaystubForPeriod = await service.paystubSummaryForPeriod(
|
||||
state.periodRange.start,
|
||||
state.periodRange.end,
|
||||
satelliteId,
|
||||
)) : await api.getHeldInfoByMonth(new PaymentInfoParameters(
|
||||
null,
|
||||
state.periodRange.end,
|
||||
satelliteId,
|
||||
));
|
||||
);
|
||||
|
||||
commit(PAYOUT_MUTATIONS.SET_HELD_PERCENT, getHeldPercentage(rootState.node.selectedSatellite.joinDate));
|
||||
commit(PAYOUT_MUTATIONS.SET_HELD_INFO, heldInfo);
|
||||
commit(PAYOUT_MUTATIONS.SET_PAYOUT_INFO, totalPaystubForPeriod);
|
||||
},
|
||||
[PAYOUT_ACTIONS.GET_TOTAL]: async function ({ commit, rootState }: any, satelliteId: string = ''): Promise<void> {
|
||||
const now = new Date();
|
||||
const totalPayoutInfo = await api.getTotal(new PaymentInfoParameters(
|
||||
new PayoutPeriod(rootState.node.selectedSatellite.joinDate.getUTCFullYear(), rootState.node.selectedSatellite.joinDate.getUTCMonth()),
|
||||
new PayoutPeriod(now.getUTCFullYear(), now.getUTCMonth()),
|
||||
satelliteId,
|
||||
));
|
||||
const start = new PayoutPeriod(rootState.node.selectedSatellite.joinDate.getUTCFullYear(), rootState.node.selectedSatellite.joinDate.getUTCMonth());
|
||||
const end = new PayoutPeriod(now.getUTCFullYear(), now.getUTCMonth());
|
||||
|
||||
const totalHeldAndPaid = await service.totalHeldAndPaid(start, end, satelliteId);
|
||||
|
||||
// TODO: move to service
|
||||
const currentBandwidthDownload = (rootState.node.egressChartData || [])
|
||||
.map(data => data.egress.usage)
|
||||
.reduce((previous, current) => previous + current, 0);
|
||||
@ -122,29 +121,31 @@ export function makePayoutModule(api: PayoutApi) {
|
||||
+ currentBandwidthAuditAndRepair * BANDWIDTH_REPAIR_PRICE_PER_TB
|
||||
+ currentDiskSpace * DISK_SPACE_PRICE_PER_TB) / TB;
|
||||
|
||||
totalHeldAndPaid.setCurrentMonthEarnings(thisMonthEarnings);
|
||||
|
||||
commit(PAYOUT_MUTATIONS.SET_HELD_PERCENT, getHeldPercentage(rootState.node.selectedSatellite.joinDate));
|
||||
commit(PAYOUT_MUTATIONS.SET_TOTAL, new TotalPayoutInfo(totalPayoutInfo.totalHeldAmount, totalPayoutInfo.totalEarnings, thisMonthEarnings));
|
||||
commit(PAYOUT_MUTATIONS.SET_TOTAL, totalHeldAndPaid);
|
||||
},
|
||||
[PAYOUT_ACTIONS.SET_PERIODS_RANGE]: function ({ commit }: any, periodRange: PayoutInfoRange): void {
|
||||
commit(PAYOUT_MUTATIONS.SET_RANGE, periodRange);
|
||||
},
|
||||
[PAYOUT_ACTIONS.GET_HELD_HISTORY]: async function ({ commit }: any): Promise<void> {
|
||||
const heldHistory = await api.getHeldHistory();
|
||||
const heldHistory = await service.allSatellitesHeldHistory();
|
||||
|
||||
commit(PAYOUT_MUTATIONS.SET_HELD_HISTORY, heldHistory);
|
||||
},
|
||||
[PAYOUT_ACTIONS.GET_PERIODS]: async function ({commit}: any, satelliteId: string = ''): Promise<void> {
|
||||
const periods = await api.getPayoutPeriods(satelliteId);
|
||||
const periods = await service.availablePeriods(satelliteId);
|
||||
|
||||
commit(PAYOUT_MUTATIONS.SET_PERIODS, periods);
|
||||
},
|
||||
[PAYOUT_ACTIONS.GET_ESTIMATION]: async function ({ commit }: any, satelliteId: string = ''): Promise<void> {
|
||||
const estimatedInfo = await api.getEstimatedInfo(satelliteId);
|
||||
const estimatedInfo = await service.estimatedPayout(satelliteId);
|
||||
|
||||
commit(PAYOUT_MUTATIONS.SET_ESTIMATION, estimatedInfo);
|
||||
},
|
||||
[PAYOUT_ACTIONS.GET_PAYOUT_HISTORY]: async function ({ commit, state }: any): Promise<void> {
|
||||
const payoutHistory = await api.getPayoutHistory(state.payoutHistoryPeriod);
|
||||
const payoutHistory = await service.payoutHistory(state.payoutHistoryPeriod);
|
||||
|
||||
commit(PAYOUT_MUTATIONS.SET_PAYOUT_HISTORY, payoutHistory);
|
||||
},
|
||||
|
@ -1,69 +1,13 @@
|
||||
// Copyright (C) 2020 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
// TODO: move comp division from api.
|
||||
const PRICE_DIVIDER: number = 10000;
|
||||
|
||||
/**
|
||||
* Holds request arguments for payout information.
|
||||
*/
|
||||
export class PaymentInfoParameters {
|
||||
public constructor(
|
||||
public start: PayoutPeriod | null = null,
|
||||
public end: PayoutPeriod = new PayoutPeriod(),
|
||||
public satelliteId: string = '',
|
||||
) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds payout information.
|
||||
*/
|
||||
export class HeldInfo {
|
||||
public constructor(
|
||||
public usageAtRest: number = 0,
|
||||
public usageGet: number = 0,
|
||||
public usagePut: number = 0,
|
||||
public usageGetRepair: number = 0,
|
||||
public usagePutRepair: number = 0,
|
||||
public usageGetAudit: number = 0,
|
||||
public compAtRest: number = 0,
|
||||
public compGet: number = 0,
|
||||
public compPut: number = 0,
|
||||
public compGetRepair: number = 0,
|
||||
public compPutRepair: number = 0,
|
||||
public compGetAudit: number = 0,
|
||||
public surgePercent: number = 0,
|
||||
public held: number = 0,
|
||||
public owed: number = 0,
|
||||
public disposed: number = 0,
|
||||
public paid: number = 0,
|
||||
public paidWithoutSurge: number = 0,
|
||||
) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents payout period month and year.
|
||||
*/
|
||||
export class PayoutPeriod {
|
||||
public constructor(
|
||||
public year: number = new Date().getUTCFullYear(),
|
||||
public month: number = new Date().getUTCMonth(),
|
||||
) {}
|
||||
|
||||
public get period(): string {
|
||||
return this.month < 9 ? `${this.year}-0${this.month + 1}` : `${this.year}-${this.month + 1}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses PayoutPeriod from string.
|
||||
* @param period string
|
||||
*/
|
||||
public static fromString(period: string): PayoutPeriod {
|
||||
const periodArray = period.split('-');
|
||||
|
||||
return new PayoutPeriod(parseInt(periodArray[0]), parseInt(periodArray[1]) - 1);
|
||||
}
|
||||
}
|
||||
import {
|
||||
EstimatedPayout,
|
||||
PayoutPeriod,
|
||||
SatelliteHeldHistory, SatellitePayoutForPeriod,
|
||||
TotalHeldAndPaid,
|
||||
TotalPaystubForPeriod,
|
||||
} from '@/storagenode/payouts/payouts';
|
||||
|
||||
/**
|
||||
* Holds 'start' and 'end' of payout period range.
|
||||
@ -75,183 +19,24 @@ export class PayoutInfoRange {
|
||||
) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds accumulated held and earned payouts.
|
||||
*/
|
||||
export class TotalPayoutInfo {
|
||||
public constructor(
|
||||
public totalHeldAmount: number = 0,
|
||||
public totalEarnings: number = 0,
|
||||
public currentMonthEarnings: number = 0,
|
||||
) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds all payout module state.
|
||||
*/
|
||||
export class PayoutState {
|
||||
public constructor (
|
||||
public heldInfo: HeldInfo = new HeldInfo(),
|
||||
public totalPaystubForPeriod: TotalPaystubForPeriod = new TotalPaystubForPeriod(),
|
||||
public periodRange: PayoutInfoRange = new PayoutInfoRange(),
|
||||
public totalHeldAmount: number = 0,
|
||||
public totalEarnings: number = 0,
|
||||
public totalHeldAndPaid: TotalHeldAndPaid = new TotalHeldAndPaid(),
|
||||
public currentMonthEarnings: number = 0,
|
||||
public heldPercentage: number = 0,
|
||||
public payoutPeriods: PayoutPeriod[] = [],
|
||||
public heldHistory: HeldHistory = new HeldHistory(),
|
||||
public payoutHistory: PayoutHistoryItem[] = [],
|
||||
public heldHistory: SatelliteHeldHistory[] = [],
|
||||
public payoutHistory: SatellitePayoutForPeriod[] = [],
|
||||
public payoutHistoryPeriod: string = '',
|
||||
public estimation: EstimatedPayout = new EstimatedPayout(),
|
||||
) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exposes all payout-related functionality.
|
||||
*/
|
||||
export interface PayoutApi {
|
||||
/**
|
||||
* Fetches held amount information by selected period.
|
||||
* @throws Error
|
||||
*/
|
||||
getHeldInfoByPeriod(paymentInfoParameters: PaymentInfoParameters): Promise<HeldInfo>;
|
||||
|
||||
/**
|
||||
* Fetches held amount information by selected month.
|
||||
* @throws Error
|
||||
*/
|
||||
getHeldInfoByMonth(paymentInfoParameters: PaymentInfoParameters): Promise<HeldInfo>;
|
||||
|
||||
/**
|
||||
* Fetches available payout periods.
|
||||
* @throws Error
|
||||
*/
|
||||
getPayoutPeriods(id: string): Promise<PayoutPeriod[]>;
|
||||
|
||||
/**
|
||||
* Fetches total payout information.
|
||||
* @throws Error
|
||||
*/
|
||||
getTotal(paymentInfoParameters: PaymentInfoParameters): Promise<TotalPayoutInfo>;
|
||||
|
||||
/**
|
||||
* Fetches held history for all satellites.
|
||||
* @throws Error
|
||||
*/
|
||||
getHeldHistory(): Promise<HeldHistory>;
|
||||
|
||||
/**
|
||||
* Fetch estimated payout information.
|
||||
* @throws Error
|
||||
*/
|
||||
getEstimatedInfo(satelliteId: string): Promise<EstimatedPayout>;
|
||||
|
||||
/**
|
||||
* Fetches payout history for all satellites.
|
||||
* @throws Error
|
||||
*/
|
||||
getPayoutHistory(period: string): Promise<PayoutHistoryItem[]>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds held history information for all satellites.
|
||||
*/
|
||||
export class HeldHistory {
|
||||
public constructor(
|
||||
public monthlyBreakdown: HeldHistoryMonthlyBreakdownItem[] = [],
|
||||
public allStats: HeldHistoryAllStatItem[] = [],
|
||||
) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains held amounts of satellite grouped by periods.
|
||||
*/
|
||||
export class HeldHistoryMonthlyBreakdownItem {
|
||||
public constructor(
|
||||
public satelliteID: string = '',
|
||||
public satelliteName: string = '',
|
||||
public age: number = 1,
|
||||
public firstPeriod: number = 0,
|
||||
public secondPeriod: number = 0,
|
||||
public thirdPeriod: number = 0,
|
||||
) {
|
||||
this.firstPeriod = this.firstPeriod / PRICE_DIVIDER;
|
||||
this.secondPeriod = this.secondPeriod / PRICE_DIVIDER;
|
||||
this.thirdPeriod = this.thirdPeriod / PRICE_DIVIDER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains held information summary of satellite grouped by periods.
|
||||
*/
|
||||
export class HeldHistoryAllStatItem {
|
||||
public constructor(
|
||||
public satelliteID: string = '',
|
||||
public satelliteName: string = '',
|
||||
public age: number = 1,
|
||||
public totalHeld: number = 0,
|
||||
public totalDisposed: number = 0,
|
||||
public joinedAt: Date = new Date(),
|
||||
) {
|
||||
this.totalHeld = this.totalHeld / PRICE_DIVIDER;
|
||||
this.totalDisposed = this.totalDisposed / PRICE_DIVIDER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,
|
||||
) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains payout information for payout history table.
|
||||
*/
|
||||
export class PayoutHistoryItem {
|
||||
public constructor(
|
||||
public satelliteID: string = '',
|
||||
public satelliteName: string = '',
|
||||
public age: number = 1,
|
||||
public earned: number = 0,
|
||||
public surge: number = 0,
|
||||
public surgePercent: number = 0,
|
||||
public held: number = 0,
|
||||
public afterHeld: number = 0,
|
||||
public disposed: number = 0,
|
||||
public paid: number = 0,
|
||||
public receipt: string = '',
|
||||
public isExitComplete: boolean = false,
|
||||
public heldPercent: number = 0,
|
||||
) {
|
||||
this.earned = this.earned / PRICE_DIVIDER;
|
||||
this.surge = this.surge / PRICE_DIVIDER;
|
||||
this.held = this.held / PRICE_DIVIDER;
|
||||
this.afterHeld = this.afterHeld / PRICE_DIVIDER;
|
||||
this.disposed = this.disposed / PRICE_DIVIDER;
|
||||
this.paid = this.paid / PRICE_DIVIDER;
|
||||
}
|
||||
}
|
||||
|
||||
export interface StoredMonthsByYear {
|
||||
[key: number]: MonthButton[];
|
||||
}
|
||||
|
@ -54,8 +54,8 @@ import { NODE_ACTIONS } from '@/app/store/modules/node';
|
||||
import { NOTIFICATIONS_ACTIONS } from '@/app/store/modules/notifications';
|
||||
import { PAYOUT_ACTIONS } from '@/app/store/modules/payout';
|
||||
import { NotificationsCursor } from '@/app/types/notifications';
|
||||
import { PayoutPeriod } from '@/app/types/payout';
|
||||
import { SatelliteInfo } from '@/storagenode/dashboard';
|
||||
import { PayoutPeriod } from '@/storagenode/payouts/payouts';
|
||||
|
||||
@Component ({
|
||||
components: {
|
||||
@ -111,7 +111,7 @@ export default class PayoutArea extends Vue {
|
||||
}
|
||||
|
||||
public get totalHeld(): number {
|
||||
return this.$store.state.payoutModule.totalHeldAmount;
|
||||
return this.$store.state.payoutModule.totalHeldAndPaid.held;
|
||||
}
|
||||
|
||||
public get heldPercentage(): number {
|
||||
|
@ -3,74 +3,31 @@
|
||||
|
||||
import {
|
||||
EstimatedPayout,
|
||||
HeldHistory,
|
||||
HeldHistoryAllStatItem,
|
||||
HeldHistoryMonthlyBreakdownItem,
|
||||
HeldInfo,
|
||||
PaymentInfoParameters,
|
||||
PayoutApi, PayoutHistoryItem,
|
||||
PayoutApi,
|
||||
PayoutPeriod,
|
||||
Paystub,
|
||||
PreviousMonthEstimatedPayout,
|
||||
TotalPayoutInfo,
|
||||
} from '@/app/types/payout';
|
||||
SatelliteHeldHistory,
|
||||
SatellitePayoutForPeriod,
|
||||
} from '@/storagenode/payouts/payouts';
|
||||
import { HttpClient } from '@/storagenode/utils/httpClient';
|
||||
|
||||
/**
|
||||
* NotificationsHttpApi is a http implementation of Notifications API.
|
||||
* Exposes all notifications-related functionality
|
||||
* PayoutHttpApi is a http implementation of Payout API.
|
||||
* Exposes all payout-related functionality
|
||||
*/
|
||||
export class PayoutHttpApi implements PayoutApi {
|
||||
private readonly client: HttpClient = new HttpClient();
|
||||
private readonly ROOT_PATH: string = '/api/heldamount';
|
||||
private PRICE_DIVIDER: number = 10000;
|
||||
|
||||
/**
|
||||
* Fetch held amount information by selected period.
|
||||
* Fetch paystubs for selected period.
|
||||
*
|
||||
* @returns held amount information
|
||||
* @returns paystubs for given period
|
||||
* @throws Error
|
||||
*/
|
||||
public async getHeldInfoByPeriod(paymentInfoParameters: PaymentInfoParameters): Promise<HeldInfo> {
|
||||
let path = `${this.ROOT_PATH}/paystubs/`;
|
||||
|
||||
if (paymentInfoParameters.start) {
|
||||
path += paymentInfoParameters.start.period + '/';
|
||||
}
|
||||
|
||||
path += paymentInfoParameters.end.period;
|
||||
|
||||
if (paymentInfoParameters.satelliteId) {
|
||||
path += '?id=' + paymentInfoParameters.satelliteId;
|
||||
}
|
||||
|
||||
return await this.getHeld(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch held amount information by selected month.
|
||||
*
|
||||
* @returns held amount information
|
||||
* @throws Error
|
||||
*/
|
||||
public async getHeldInfoByMonth(paymentInfoParameters: PaymentInfoParameters): Promise<HeldInfo> {
|
||||
let path = `${this.ROOT_PATH}/paystubs/`;
|
||||
|
||||
path += paymentInfoParameters.end.period;
|
||||
|
||||
if (paymentInfoParameters.satelliteId) {
|
||||
path += '?id=' + paymentInfoParameters.satelliteId;
|
||||
}
|
||||
|
||||
return await this.getHeld(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch total payout information.
|
||||
*
|
||||
* @returns total payout information
|
||||
* @throws Error
|
||||
*/
|
||||
public async getTotal(paymentInfoParameters: PaymentInfoParameters): Promise<TotalPayoutInfo> {
|
||||
public async getPaystubsForPeriod(paymentInfoParameters: PaymentInfoParameters): Promise<Paystub[]> {
|
||||
let path = `${this.ROOT_PATH}/paystubs/`;
|
||||
|
||||
if (paymentInfoParameters.start) {
|
||||
@ -86,28 +43,32 @@ export class PayoutHttpApi implements PayoutApi {
|
||||
const response = await this.client.get(path);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('can not get total payout information');
|
||||
throw new Error('can not get held information');
|
||||
}
|
||||
|
||||
const data: any = await response.json() || [];
|
||||
const data: any[] = await response.json() || [];
|
||||
|
||||
if (!Array.isArray(data)) {
|
||||
return new TotalPayoutInfo(data.held, data.paid);
|
||||
}
|
||||
|
||||
let held: number = 0;
|
||||
let paid: number = 0;
|
||||
|
||||
data.forEach((paystub: any) => {
|
||||
held += (paystub.held - paystub.disposed) / this.PRICE_DIVIDER;
|
||||
paid += paystub.paid / this.PRICE_DIVIDER;
|
||||
return data.map((paystubJson: any) => {
|
||||
return new Paystub(
|
||||
paystubJson.usageAtRest,
|
||||
paystubJson.usageGet,
|
||||
paystubJson.usagePut,
|
||||
paystubJson.usageGetRepair,
|
||||
paystubJson.usagePutRepair,
|
||||
paystubJson.usageGetAudit,
|
||||
paystubJson.compAtRest,
|
||||
paystubJson.compGet,
|
||||
paystubJson.compPut,
|
||||
paystubJson.compGetRepair,
|
||||
paystubJson.compPutRepair,
|
||||
paystubJson.compGetAudit,
|
||||
paystubJson.surgePercent,
|
||||
paystubJson.held,
|
||||
paystubJson.owed,
|
||||
paystubJson.disposed,
|
||||
paystubJson.paid,
|
||||
);
|
||||
});
|
||||
|
||||
return new TotalPayoutInfo(
|
||||
held,
|
||||
paid,
|
||||
0,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -142,7 +103,7 @@ export class PayoutHttpApi implements PayoutApi {
|
||||
* @returns payout information
|
||||
* @throws Error
|
||||
*/
|
||||
public async getPayoutHistory(period): Promise<PayoutHistoryItem[]> {
|
||||
public async getPayoutHistory(period): Promise<SatellitePayoutForPeriod[]> {
|
||||
const path = `${this.ROOT_PATH}/payout-history/${period}`;
|
||||
|
||||
const response = await this.client.get(path);
|
||||
@ -154,7 +115,7 @@ export class PayoutHttpApi implements PayoutApi {
|
||||
const data: any = await response.json() || [];
|
||||
|
||||
return data.map((payoutHistoryItem: any) => {
|
||||
return new PayoutHistoryItem(
|
||||
return new SatellitePayoutForPeriod(
|
||||
payoutHistoryItem.satelliteID,
|
||||
payoutHistoryItem.satelliteURL,
|
||||
payoutHistoryItem.age,
|
||||
@ -178,7 +139,7 @@ export class PayoutHttpApi implements PayoutApi {
|
||||
* @returns total payout information
|
||||
* @throws Error
|
||||
*/
|
||||
public async getHeldHistory(): Promise<HeldHistory> {
|
||||
public async getHeldHistory(): Promise<SatelliteHeldHistory[]> {
|
||||
const path = `${this.ROOT_PATH}/held-history/`;
|
||||
|
||||
const response = await this.client.get(path);
|
||||
@ -189,29 +150,18 @@ export class PayoutHttpApi implements PayoutApi {
|
||||
|
||||
const data: any = await response.json() || [];
|
||||
|
||||
const monthlyBreakdown = data.map((historyItem: any) => {
|
||||
return new HeldHistoryMonthlyBreakdownItem(
|
||||
return data.map((historyItem: any) => {
|
||||
return new SatelliteHeldHistory(
|
||||
historyItem.satelliteID,
|
||||
historyItem.satelliteName,
|
||||
historyItem.age,
|
||||
historyItem.firstPeriod,
|
||||
historyItem.secondPeriod,
|
||||
historyItem.thirdPeriod,
|
||||
historyItem.totalHeld,
|
||||
historyItem.totalDisposed,
|
||||
new Date(historyItem.joinedAt),
|
||||
);
|
||||
});
|
||||
|
||||
const allStats = data.map((historyItem: any) => {
|
||||
return new HeldHistoryAllStatItem(
|
||||
historyItem.satelliteID,
|
||||
historyItem.satelliteName,
|
||||
historyItem.age,
|
||||
historyItem.totalHeld,
|
||||
historyItem.totalDisposed,
|
||||
new Date(historyItem.joinedAt),
|
||||
);
|
||||
});
|
||||
|
||||
return new HeldHistory(monthlyBreakdown, allStats);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -220,7 +170,7 @@ export class PayoutHttpApi implements PayoutApi {
|
||||
* @returns estimated payout information
|
||||
* @throws Error
|
||||
*/
|
||||
public async getEstimatedInfo(satelliteId: string): Promise<EstimatedPayout> {
|
||||
public async getEstimatedPayout(satelliteId: string): Promise<EstimatedPayout> {
|
||||
let path = '/api/sno/estimated-payout';
|
||||
|
||||
if (satelliteId) {
|
||||
@ -233,7 +183,7 @@ export class PayoutHttpApi implements PayoutApi {
|
||||
throw new Error('can not get estimated payout information');
|
||||
}
|
||||
|
||||
const data: any = await response.json() || [];
|
||||
const data: any = await response.json() || new EstimatedPayout();
|
||||
|
||||
return new EstimatedPayout(
|
||||
new PreviousMonthEstimatedPayout(
|
||||
@ -260,87 +210,4 @@ export class PayoutHttpApi implements PayoutApi {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch total payout information depends on month.
|
||||
*
|
||||
* @returns total payout information
|
||||
* @throws Error
|
||||
*/
|
||||
public async getHeld(path): Promise<HeldInfo> {
|
||||
const response = await this.client.get(path);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('can not get held information');
|
||||
}
|
||||
|
||||
const data: any[] = await response.json();
|
||||
|
||||
if (!data || data.length === 0) {
|
||||
throw new Error('no payout data for selected period');
|
||||
}
|
||||
|
||||
let usageAtRest: number = 0;
|
||||
let usageGet: number = 0;
|
||||
let usagePut: number = 0;
|
||||
let usageGetRepair: number = 0;
|
||||
let usagePutRepair: number = 0;
|
||||
let usageGetAudit: number = 0;
|
||||
let compAtRest: number = 0;
|
||||
let compGet: number = 0;
|
||||
let compPut: number = 0;
|
||||
let compGetRepair: number = 0;
|
||||
let compPutRepair: number = 0;
|
||||
let compGetAudit: number = 0;
|
||||
let held: number = 0;
|
||||
let owed: number = 0;
|
||||
let disposed: number = 0;
|
||||
let paid: number = 0;
|
||||
let surgePercent: number = 0;
|
||||
let paidWithoutSurge: number = 0;
|
||||
|
||||
data.forEach((paystub: any) => {
|
||||
const surge = paystub.surgePercent === 0 ? 1 : paystub.surgePercent / 100;
|
||||
|
||||
usageAtRest += paystub.usageAtRest;
|
||||
usageGet += paystub.usageGet;
|
||||
usagePut += paystub.usagePut;
|
||||
usageGetRepair += paystub.usageGetRepair;
|
||||
usagePutRepair += paystub.usagePutRepair;
|
||||
usageGetAudit += paystub.usageGetAudit;
|
||||
compAtRest += paystub.compAtRest / this.PRICE_DIVIDER;
|
||||
compGet += paystub.compGet / this.PRICE_DIVIDER;
|
||||
compPut += paystub.compPut / this.PRICE_DIVIDER;
|
||||
compGetRepair += paystub.compGetRepair / this.PRICE_DIVIDER;
|
||||
compPutRepair += paystub.compPutRepair / this.PRICE_DIVIDER;
|
||||
compGetAudit += paystub.compGetAudit / this.PRICE_DIVIDER;
|
||||
held += paystub.held / this.PRICE_DIVIDER;
|
||||
owed += paystub.owed / this.PRICE_DIVIDER;
|
||||
disposed += paystub.disposed / this.PRICE_DIVIDER;
|
||||
paid += paystub.paid / this.PRICE_DIVIDER;
|
||||
surgePercent = paystub.surgePercent;
|
||||
paidWithoutSurge += paystub.paid / this.PRICE_DIVIDER / surge;
|
||||
});
|
||||
|
||||
return new HeldInfo(
|
||||
usageAtRest,
|
||||
usageGet,
|
||||
usagePut,
|
||||
usageGetRepair,
|
||||
usagePutRepair,
|
||||
usageGetAudit,
|
||||
compAtRest,
|
||||
compGet,
|
||||
compPut,
|
||||
compGetRepair,
|
||||
compPutRepair,
|
||||
compGetAudit,
|
||||
surgePercent,
|
||||
held,
|
||||
owed,
|
||||
disposed,
|
||||
paid,
|
||||
paidWithoutSurge,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
276
web/storagenode/src/storagenode/payouts/payouts.ts
Normal file
276
web/storagenode/src/storagenode/payouts/payouts.ts
Normal file
@ -0,0 +1,276 @@
|
||||
// Copyright (C) 2020 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
import { getMonthsBeforeNow } from '@/app/utils/payout';
|
||||
|
||||
/**
|
||||
* Exposes all payout-related functionality.
|
||||
*/
|
||||
export interface PayoutApi {
|
||||
/**
|
||||
* Fetches paystubs by selected period.
|
||||
* @throws Error
|
||||
*/
|
||||
getPaystubsForPeriod(paymentInfoParameters: PaymentInfoParameters): Promise<Paystub[]>;
|
||||
|
||||
/**
|
||||
* Fetches available payout periods.
|
||||
* @throws Error
|
||||
*/
|
||||
getPayoutPeriods(id: string): Promise<PayoutPeriod[]>;
|
||||
|
||||
/**
|
||||
* Fetches held history for all satellites.
|
||||
* @throws Error
|
||||
*/
|
||||
getHeldHistory(): Promise<SatelliteHeldHistory[]>;
|
||||
|
||||
/**
|
||||
* Fetch estimated payout information.
|
||||
* @throws Error
|
||||
*/
|
||||
getEstimatedPayout(satelliteId: string): Promise<EstimatedPayout>;
|
||||
|
||||
/**
|
||||
* Fetches payout history for all satellites.
|
||||
* @throws Error
|
||||
*/
|
||||
getPayoutHistory(period: string): Promise<SatellitePayoutForPeriod[]>;
|
||||
}
|
||||
|
||||
// TODO: move to config.
|
||||
/**
|
||||
* Divider to convert payout amounts to cents.
|
||||
*/
|
||||
const PRICE_DIVIDER: number = 10000;
|
||||
|
||||
/**
|
||||
* Represents payout period month and year.
|
||||
*/
|
||||
export class PayoutPeriod {
|
||||
public constructor(
|
||||
public year: number = new Date().getUTCFullYear(),
|
||||
public month: number = new Date().getUTCMonth(),
|
||||
) {}
|
||||
|
||||
public get period(): string {
|
||||
return this.month < 9 ? `${this.year}-0${this.month + 1}` : `${this.year}-${this.month + 1}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses PayoutPeriod from string.
|
||||
* @param period string
|
||||
*/
|
||||
public static fromString(period: string): PayoutPeriod {
|
||||
const periodArray = period.split('-');
|
||||
|
||||
return new PayoutPeriod(parseInt(periodArray[0]), parseInt(periodArray[1]) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds request arguments for payout information.
|
||||
*/
|
||||
export class PaymentInfoParameters {
|
||||
public constructor(
|
||||
public start: PayoutPeriod | null = null,
|
||||
public end: PayoutPeriod = new PayoutPeriod(),
|
||||
public satelliteId: string = '',
|
||||
) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* PayStub is an entity that holds usage and cash amounts that will be paid to storagenode operator after for month period.
|
||||
*/
|
||||
export class Paystub {
|
||||
public constructor(
|
||||
public usageAtRest: number = 0,
|
||||
public usageGet: number = 0,
|
||||
public usagePut: number = 0,
|
||||
public usageGetRepair: number = 0,
|
||||
public usagePutRepair: number = 0,
|
||||
public usageGetAudit: number = 0,
|
||||
public compAtRest: number = 0,
|
||||
public compGet: number = 0,
|
||||
public compPut: number = 0,
|
||||
public compGetRepair: number = 0,
|
||||
public compPutRepair: number = 0,
|
||||
public compGetAudit: number = 0,
|
||||
public surgePercent: number = 0,
|
||||
public held: number = 0,
|
||||
public owed: number = 0,
|
||||
public disposed: number = 0,
|
||||
public paid: number = 0,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Returns payout amount multiplier.
|
||||
*/
|
||||
public get surgeMultiplier(): number {
|
||||
// 0 in backend uses instead of "without multiplier"
|
||||
return this.surgePercent === 0 ? 1 : this.surgePercent / 100;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary of paystubs by period.
|
||||
* Payout amounts converted to cents.
|
||||
*/
|
||||
export class TotalPaystubForPeriod {
|
||||
public usageAtRest: number = 0;
|
||||
public usageGet: number = 0;
|
||||
public usagePut: number = 0;
|
||||
public usageGetRepair: number = 0;
|
||||
public usagePutRepair: number = 0;
|
||||
public usageGetAudit: number = 0;
|
||||
public compAtRest: number = 0;
|
||||
public compGet: number = 0;
|
||||
public compPut: number = 0;
|
||||
public compGetRepair: number = 0;
|
||||
public compPutRepair: number = 0;
|
||||
public compGetAudit: number = 0;
|
||||
public surgePercent: number = 0;
|
||||
public held: number = 0;
|
||||
public owed: number = 0;
|
||||
public disposed: number = 0;
|
||||
public paid: number = 0;
|
||||
public paidWithoutSurge: number = 0;
|
||||
|
||||
public constructor(
|
||||
paystubs: Paystub[] = [],
|
||||
) {
|
||||
paystubs.forEach(paystub => {
|
||||
this.usageAtRest += paystub.usageAtRest;
|
||||
this.usageGet += paystub.usageGet;
|
||||
this.usagePut += paystub.usagePut;
|
||||
this.usageGetRepair += paystub.usageGetRepair;
|
||||
this.usagePutRepair += paystub.usagePutRepair;
|
||||
this.usageGetAudit += paystub.usageGetAudit;
|
||||
this.compAtRest += this.convertToCents(paystub.compAtRest);
|
||||
this.compGet += this.convertToCents(paystub.compGet);
|
||||
this.compPut += this.convertToCents(paystub.compPut);
|
||||
this.compGetRepair += this.convertToCents(paystub.compGetRepair);
|
||||
this.compPutRepair += this.convertToCents(paystub.compPutRepair);
|
||||
this.compGetAudit += this.convertToCents(paystub.compGetAudit);
|
||||
this.held += this.convertToCents(paystub.held);
|
||||
this.owed += this.convertToCents(paystub.owed);
|
||||
this.disposed += this.convertToCents(paystub.disposed);
|
||||
this.paid += this.convertToCents(paystub.paid);
|
||||
this.surgePercent = this.convertToCents(paystub.surgePercent);
|
||||
this.paidWithoutSurge += this.convertToCents(paystub.paid) / paystub.surgeMultiplier;
|
||||
});
|
||||
}
|
||||
|
||||
private convertToCents(value: number): number {
|
||||
return value / PRICE_DIVIDER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds accumulated held and earned payouts.
|
||||
*/
|
||||
export class TotalHeldAndPaid {
|
||||
public held: number = 0;
|
||||
public paid: number = 0;
|
||||
// TODO: remove
|
||||
public currentMonthEarnings: number = 0;
|
||||
|
||||
public constructor(
|
||||
paystubs: Paystub[] = [],
|
||||
) {
|
||||
paystubs.forEach(paystub => {
|
||||
this.held += this.convertToCents(paystub.held - paystub.disposed);
|
||||
this.paid += this.convertToCents(paystub.paid);
|
||||
});
|
||||
}
|
||||
|
||||
public setCurrentMonthEarnings(value: number): void {
|
||||
this.currentMonthEarnings = value;
|
||||
}
|
||||
|
||||
private convertToCents(value: number): number {
|
||||
return value / PRICE_DIVIDER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds held history information for all satellites.
|
||||
*/
|
||||
export class SatelliteHeldHistory {
|
||||
public constructor(
|
||||
public satelliteID: string = '',
|
||||
public satelliteName: string = '',
|
||||
public firstPeriod: number = 0,
|
||||
public secondPeriod: number = 0,
|
||||
public thirdPeriod: number = 0,
|
||||
public totalHeld: number = 0,
|
||||
public totalDisposed: number = 0,
|
||||
public joinedAt: Date = new Date(),
|
||||
) {
|
||||
this.totalHeld = this.totalHeld / PRICE_DIVIDER;
|
||||
this.totalDisposed = this.totalDisposed / PRICE_DIVIDER;
|
||||
this.firstPeriod = this.firstPeriod / PRICE_DIVIDER;
|
||||
this.secondPeriod = this.secondPeriod / PRICE_DIVIDER;
|
||||
this.thirdPeriod = this.thirdPeriod / PRICE_DIVIDER;
|
||||
}
|
||||
|
||||
public get monthsWithNode(): number {
|
||||
return getMonthsBeforeNow(this.joinedAt);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,
|
||||
) {}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Contains payout information for payout history table.
|
||||
*/
|
||||
export class SatellitePayoutForPeriod {
|
||||
public constructor(
|
||||
public satelliteID: string = '',
|
||||
public satelliteName: string = '',
|
||||
public age: number = 1,
|
||||
public earned: number = 0,
|
||||
public surge: number = 0,
|
||||
public surgePercent: number = 0,
|
||||
public held: number = 0,
|
||||
public afterHeld: number = 0,
|
||||
public disposed: number = 0,
|
||||
public paid: number = 0,
|
||||
public receipt: string = '',
|
||||
public isExitComplete: boolean = false,
|
||||
public heldPercent: number = 0,
|
||||
) {
|
||||
this.earned = this.earned / PRICE_DIVIDER;
|
||||
this.surge = this.surge / PRICE_DIVIDER;
|
||||
this.held = this.held / PRICE_DIVIDER;
|
||||
this.afterHeld = this.afterHeld / PRICE_DIVIDER;
|
||||
this.disposed = this.disposed / PRICE_DIVIDER;
|
||||
this.paid = this.paid / PRICE_DIVIDER;
|
||||
}
|
||||
}
|
82
web/storagenode/src/storagenode/payouts/service.ts
Normal file
82
web/storagenode/src/storagenode/payouts/service.ts
Normal file
@ -0,0 +1,82 @@
|
||||
// Copyright (C) 2020 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
import {
|
||||
EstimatedPayout,
|
||||
PaymentInfoParameters,
|
||||
PayoutApi,
|
||||
PayoutPeriod,
|
||||
Paystub,
|
||||
SatelliteHeldHistory,
|
||||
SatellitePayoutForPeriod,
|
||||
TotalHeldAndPaid,
|
||||
TotalPaystubForPeriod,
|
||||
} from '@/storagenode/payouts/payouts';
|
||||
|
||||
/**
|
||||
* PayoutService is used to store and handle node paystub information.
|
||||
* PayoutService exposes a business logic related to payouts.
|
||||
*/
|
||||
export class PayoutService {
|
||||
private readonly payouts: PayoutApi;
|
||||
|
||||
public constructor(api: PayoutApi) {
|
||||
this.payouts = api;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets summary of paystubs for given period.
|
||||
* @param start period start
|
||||
* @param end period end
|
||||
* @param satelliteId
|
||||
*/
|
||||
public async paystubSummaryForPeriod(start: PayoutPeriod, end: PayoutPeriod, satelliteId?: string): Promise<TotalPaystubForPeriod> {
|
||||
const paystubs: Paystub[] = await this.payouts.getPaystubsForPeriod(new PaymentInfoParameters(start, end, satelliteId));
|
||||
|
||||
return new TotalPaystubForPeriod(paystubs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets held and paid summary for given period.
|
||||
* @param start period start
|
||||
* @param end period end
|
||||
* @param satelliteId
|
||||
*/
|
||||
public async totalHeldAndPaid(start: PayoutPeriod, end: PayoutPeriod, satelliteId: string): Promise<TotalHeldAndPaid> {
|
||||
const paystubs: Paystub[] = await this.payouts.getPaystubsForPeriod(new PaymentInfoParameters(start, end, satelliteId));
|
||||
|
||||
return new TotalHeldAndPaid(paystubs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets list of payout periods that have paystubs for selected satellite.
|
||||
* If satelliteId is not provided returns periods for all satellites.
|
||||
* @param satelliteId
|
||||
*/
|
||||
public async availablePeriods(satelliteId: string): Promise<PayoutPeriod[]> {
|
||||
return await this.payouts.getPayoutPeriods(satelliteId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets list of payout history items for given period by satellites.
|
||||
* @param payoutHistoryPeriod year and month representation
|
||||
*/
|
||||
public async payoutHistory(payoutHistoryPeriod: string): Promise<SatellitePayoutForPeriod[]> {
|
||||
return await this.payouts.getPayoutHistory(payoutHistoryPeriod);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets list of held history for all satellites.
|
||||
*/
|
||||
public async allSatellitesHeldHistory(): Promise<SatelliteHeldHistory[]> {
|
||||
return await this.payouts.getHeldHistory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets estimated payout when no data in paystub.
|
||||
* @param satelliteId
|
||||
*/
|
||||
public async estimatedPayout(satelliteId: string): Promise<EstimatedPayout> {
|
||||
return await this.payouts.getEstimatedPayout(satelliteId);
|
||||
}
|
||||
}
|
@ -6,8 +6,9 @@ import Vuex from 'vuex';
|
||||
import HeldHistoryAllStatsTable from '@/app/components/payments/HeldHistoryAllStatsTable.vue';
|
||||
|
||||
import { makePayoutModule, PAYOUT_MUTATIONS } from '@/app/store/modules/payout';
|
||||
import { HeldHistory, HeldHistoryAllStatItem } from '@/app/types/payout';
|
||||
import { PayoutHttpApi } from '@/storagenode/api/payout';
|
||||
import { SatelliteHeldHistory } from '@/storagenode/payouts/payouts';
|
||||
import { PayoutService } from '@/storagenode/payouts/service';
|
||||
import { createLocalVue, shallowMount } from '@vue/test-utils';
|
||||
|
||||
const localVue = createLocalVue();
|
||||
@ -18,7 +19,8 @@ localVue.filter('centsToDollars', (cents: number): string => {
|
||||
});
|
||||
|
||||
const payoutApi = new PayoutHttpApi();
|
||||
const payoutModule = makePayoutModule(payoutApi);
|
||||
const payoutService = new PayoutService(payoutApi);
|
||||
const payoutModule = makePayoutModule(payoutApi, payoutService);
|
||||
|
||||
const store = new Vuex.Store({ modules: { payoutModule }});
|
||||
|
||||
@ -30,14 +32,13 @@ describe('HeldHistoryAllStatsTable', (): void => {
|
||||
});
|
||||
|
||||
const testJoinAt = new Date(Date.UTC(2020, 0, 30));
|
||||
const testHeldHistory = [
|
||||
new SatelliteHeldHistory('1', 'name1', 1, 50000, 0, 0, 1, testJoinAt),
|
||||
new SatelliteHeldHistory('2', 'name2', 5, 50000, 422280, 0, 0, testJoinAt),
|
||||
new SatelliteHeldHistory('3', 'name3', 6, 50000, 7333880, 7852235, 0, testJoinAt),
|
||||
];
|
||||
|
||||
await store.commit(PAYOUT_MUTATIONS.SET_HELD_HISTORY, new HeldHistory(
|
||||
[],
|
||||
[
|
||||
new HeldHistoryAllStatItem('1', 'name1', 1, 50000, 20000, testJoinAt),
|
||||
new HeldHistoryAllStatItem('2', 'name2', 5, 40000, 30000, testJoinAt),
|
||||
],
|
||||
));
|
||||
await store.commit(PAYOUT_MUTATIONS.SET_HELD_HISTORY, testHeldHistory);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
import HeldHistoryAllStatsTableItemSmall from '@/app/components/payments/HeldHistoryAllStatsTableItemSmall.vue';
|
||||
|
||||
import { HeldHistoryAllStatItem } from '@/app/types/payout';
|
||||
import { SatelliteHeldHistory } from '@/storagenode/payouts/payouts';
|
||||
import { createLocalVue, shallowMount } from '@vue/test-utils';
|
||||
|
||||
const localVue = createLocalVue();
|
||||
@ -18,12 +18,14 @@ describe('HeldHistoryAllStatsTableItemSmall', (): void => {
|
||||
|
||||
const wrapper = shallowMount(HeldHistoryAllStatsTableItemSmall, {
|
||||
propsData: {
|
||||
heldHistoryItem: new HeldHistoryAllStatItem(
|
||||
heldHistoryItem: new SatelliteHeldHistory(
|
||||
'1',
|
||||
'name1',
|
||||
7,
|
||||
45000,
|
||||
8000,
|
||||
6,
|
||||
50000,
|
||||
7333880,
|
||||
7852235,
|
||||
757576,
|
||||
testJoinAt,
|
||||
),
|
||||
},
|
||||
|
@ -7,13 +7,15 @@ import HeldHistoryArea from '@/app/components/payments/HeldHistoryArea.vue';
|
||||
|
||||
import { makePayoutModule } from '@/app/store/modules/payout';
|
||||
import { PayoutHttpApi } from '@/storagenode/api/payout';
|
||||
import { PayoutService } from '@/storagenode/payouts/service';
|
||||
import { createLocalVue, shallowMount } from '@vue/test-utils';
|
||||
|
||||
const localVue = createLocalVue();
|
||||
localVue.use(Vuex);
|
||||
|
||||
const payoutApi = new PayoutHttpApi();
|
||||
const payoutModule = makePayoutModule(payoutApi);
|
||||
const payoutService = new PayoutService(payoutApi);
|
||||
const payoutModule = makePayoutModule(payoutApi, payoutService);
|
||||
|
||||
const store = new Vuex.Store({ modules: { payoutModule }});
|
||||
|
||||
|
@ -6,8 +6,9 @@ import Vuex from 'vuex';
|
||||
import HeldHistoryMonthlyBreakdownTable from '@/app/components/payments/HeldHistoryMonthlyBreakdownTable.vue';
|
||||
|
||||
import { makePayoutModule, PAYOUT_MUTATIONS } from '@/app/store/modules/payout';
|
||||
import { HeldHistory, HeldHistoryMonthlyBreakdownItem } from '@/app/types/payout';
|
||||
import { PayoutHttpApi } from '@/storagenode/api/payout';
|
||||
import { SatelliteHeldHistory } from '@/storagenode/payouts/payouts';
|
||||
import { PayoutService } from '@/storagenode/payouts/service';
|
||||
import { createLocalVue, shallowMount } from '@vue/test-utils';
|
||||
|
||||
const localVue = createLocalVue();
|
||||
@ -18,7 +19,8 @@ localVue.filter('centsToDollars', (cents: number): string => {
|
||||
});
|
||||
|
||||
const payoutApi = new PayoutHttpApi();
|
||||
const payoutModule = makePayoutModule(payoutApi);
|
||||
const payoutService = new PayoutService(payoutApi);
|
||||
const payoutModule = makePayoutModule(payoutApi, payoutService);
|
||||
|
||||
const store = new Vuex.Store({ modules: { payoutModule }});
|
||||
|
||||
@ -29,11 +31,13 @@ describe('HeldHistoryMonthlyBreakdownTable', (): void => {
|
||||
localVue,
|
||||
});
|
||||
|
||||
await store.commit(PAYOUT_MUTATIONS.SET_HELD_HISTORY, new HeldHistory([
|
||||
new HeldHistoryMonthlyBreakdownItem('1', 'name1', 1, 50000, 0, 0),
|
||||
new HeldHistoryMonthlyBreakdownItem('2', 'name2', 5, 50000, 422280, 0),
|
||||
new HeldHistoryMonthlyBreakdownItem('3', 'name3', 6, 50000, 7333880, 7852235),
|
||||
]));
|
||||
const testJoinedAt = new Date(2020, 1, 20);
|
||||
|
||||
await store.commit(PAYOUT_MUTATIONS.SET_HELD_HISTORY, [
|
||||
new SatelliteHeldHistory('1', 'name1', 1, 50000, 0, 0, 0, testJoinedAt),
|
||||
new SatelliteHeldHistory('2', 'name2', 5, 50000, 422280, 0, 0 , testJoinedAt),
|
||||
new SatelliteHeldHistory('3', 'name3', 6, 50000, 7333880, 7852235, 0, testJoinedAt),
|
||||
]);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
import HeldHistoryMonthlyBreakdownTableItemSmall from '@/app/components/payments/HeldHistoryMonthlyBreakdownTableItemSmall.vue';
|
||||
|
||||
import { HeldHistoryMonthlyBreakdownItem } from '@/app/types/payout';
|
||||
import { SatelliteHeldHistory } from '@/storagenode/payouts/payouts';
|
||||
import { createLocalVue, shallowMount } from '@vue/test-utils';
|
||||
|
||||
const localVue = createLocalVue();
|
||||
@ -16,13 +16,15 @@ describe('HeldHistoryMonthlyBreakdownTableSmall', (): void => {
|
||||
it('renders correctly with actual values', async (): Promise<void> => {
|
||||
const wrapper = shallowMount(HeldHistoryMonthlyBreakdownTableItemSmall, {
|
||||
propsData: {
|
||||
heldHistoryItem: new HeldHistoryMonthlyBreakdownItem(
|
||||
heldHistoryItem: new SatelliteHeldHistory(
|
||||
'1',
|
||||
'name1',
|
||||
6,
|
||||
50000,
|
||||
7333880,
|
||||
7852235,
|
||||
757576,
|
||||
new Date(2020, 1, 20),
|
||||
),
|
||||
},
|
||||
localVue,
|
||||
|
@ -12,6 +12,7 @@ import { makeNodeModule, NODE_MUTATIONS } from '@/app/store/modules/node';
|
||||
import { makePayoutModule, PAYOUT_MUTATIONS } from '@/app/store/modules/payout';
|
||||
import { PayoutHttpApi } from '@/storagenode/api/payout';
|
||||
import { SNOApi } from '@/storagenode/api/storagenode';
|
||||
import { PayoutService } from '@/storagenode/payouts/service';
|
||||
import { Satellites } from '@/storagenode/satellite';
|
||||
import { createLocalVue, shallowMount } from '@vue/test-utils';
|
||||
|
||||
@ -40,7 +41,8 @@ localVue.directive('click-outside', {
|
||||
});
|
||||
|
||||
const payoutApi = new PayoutHttpApi();
|
||||
const payoutModule = makePayoutModule(payoutApi);
|
||||
const payoutService = new PayoutService(payoutApi);
|
||||
const payoutModule = makePayoutModule(payoutApi, payoutService);
|
||||
const nodeApi = new SNOApi();
|
||||
const nodeModule = makeNodeModule(nodeApi);
|
||||
|
||||
|
@ -6,8 +6,9 @@ import Vuex from 'vuex';
|
||||
import PayoutHistoryTable from '@/app/components/payments/PayoutHistoryTable.vue';
|
||||
|
||||
import { makePayoutModule, PAYOUT_MUTATIONS } from '@/app/store/modules/payout';
|
||||
import { PayoutHistoryItem } from '@/app/types/payout';
|
||||
import { PayoutHttpApi } from '@/storagenode/api/payout';
|
||||
import { SatellitePayoutForPeriod } from '@/storagenode/payouts/payouts';
|
||||
import { PayoutService } from '@/storagenode/payouts/service';
|
||||
import { createLocalVue, shallowMount } from '@vue/test-utils';
|
||||
|
||||
const localVue = createLocalVue();
|
||||
@ -18,17 +19,18 @@ localVue.filter('centsToDollars', (cents: number): string => {
|
||||
});
|
||||
|
||||
const payoutApi = new PayoutHttpApi();
|
||||
const payoutModule = makePayoutModule(payoutApi);
|
||||
const payoutService = new PayoutService(payoutApi);
|
||||
const payoutModule = makePayoutModule(payoutApi, payoutService);
|
||||
|
||||
const store = new Vuex.Store({ modules: { payoutModule }});
|
||||
|
||||
describe('PayoutHistoryTable', (): void => {
|
||||
it('renders correctly with actual values', async (): Promise<void> => {
|
||||
await store.commit(PAYOUT_MUTATIONS.SET_PAYOUT_HISTORY, [
|
||||
new PayoutHistoryItem('1', 'name1', 1, 100000, 1200000, 140,
|
||||
new SatellitePayoutForPeriod('1', 'name1', 1, 100000, 1200000, 140,
|
||||
500000, 600000, 200000, 800000, 'receipt1', false,
|
||||
),
|
||||
new PayoutHistoryItem('2', 'name2', 16, 100000, 1200000, 140,
|
||||
new SatellitePayoutForPeriod('2', 'name2', 16, 100000, 1200000, 140,
|
||||
500000, 600000, 200000, 800000, 'receipt2', true,
|
||||
),
|
||||
]);
|
||||
|
@ -6,8 +6,9 @@ import Vuex from 'vuex';
|
||||
import PayoutHistoryTableItem from '@/app/components/payments/PayoutHistoryTableItem.vue';
|
||||
|
||||
import { makePayoutModule } from '@/app/store/modules/payout';
|
||||
import { PayoutHistoryItem } from '@/app/types/payout';
|
||||
import { PayoutHttpApi } from '@/storagenode/api/payout';
|
||||
import { SatellitePayoutForPeriod } from '@/storagenode/payouts/payouts';
|
||||
import { PayoutService } from '@/storagenode/payouts/service';
|
||||
import { createLocalVue, shallowMount } from '@vue/test-utils';
|
||||
|
||||
const localVue = createLocalVue();
|
||||
@ -18,7 +19,8 @@ localVue.filter('centsToDollars', (cents: number): string => {
|
||||
});
|
||||
|
||||
const payoutApi = new PayoutHttpApi();
|
||||
const payoutModule = makePayoutModule(payoutApi);
|
||||
const payoutService = new PayoutService(payoutApi);
|
||||
const payoutModule = makePayoutModule(payoutApi, payoutService);
|
||||
|
||||
const store = new Vuex.Store({ modules: { payoutModule }});
|
||||
|
||||
@ -28,7 +30,7 @@ describe('PayoutHistoryTableItem', (): void => {
|
||||
store,
|
||||
localVue,
|
||||
propsData: {
|
||||
historyItem: new PayoutHistoryItem('1', 'name1', 1, 100000, 1200000, 140,
|
||||
historyItem: new SatellitePayoutForPeriod('1', 'name1', 1, 100000, 1200000, 140,
|
||||
500000, 600000, 200000, 800000, 'receipt1', false, 75,
|
||||
),
|
||||
},
|
||||
|
@ -6,8 +6,9 @@ import Vuex from 'vuex';
|
||||
import TotalPayoutArea from '@/app/components/TotalPayoutArea.vue';
|
||||
|
||||
import { makePayoutModule, PAYOUT_MUTATIONS } from '@/app/store/modules/payout';
|
||||
import { TotalPayoutInfo } from '@/app/types/payout';
|
||||
import { PayoutHttpApi } from '@/storagenode/api/payout';
|
||||
import { Paystub, TotalHeldAndPaid } from '@/storagenode/payouts/payouts';
|
||||
import { PayoutService } from '@/storagenode/payouts/service';
|
||||
import { createLocalVue, shallowMount } from '@vue/test-utils';
|
||||
|
||||
const localVue = createLocalVue();
|
||||
@ -18,11 +19,12 @@ localVue.filter('centsToDollars', (cents: number): string => {
|
||||
});
|
||||
|
||||
const payoutApi = new PayoutHttpApi();
|
||||
const payoutModule = makePayoutModule(payoutApi);
|
||||
const payoutService = new PayoutService(payoutApi);
|
||||
const payoutModule = makePayoutModule(payoutApi, payoutService);
|
||||
|
||||
const store = new Vuex.Store({ modules: { payoutModule }});
|
||||
|
||||
describe('TotalPayoutInfo', (): void => {
|
||||
describe('TotalPayoutArea', (): void => {
|
||||
it('renders correctly', (): void => {
|
||||
const wrapper = shallowMount(TotalPayoutArea, {
|
||||
store,
|
||||
@ -37,8 +39,21 @@ describe('TotalPayoutInfo', (): void => {
|
||||
store,
|
||||
localVue,
|
||||
});
|
||||
const paystub = new Paystub();
|
||||
paystub.held = 600000;
|
||||
paystub.disposed = 100000;
|
||||
paystub.paid = 1000000;
|
||||
|
||||
await store.commit(PAYOUT_MUTATIONS.SET_TOTAL, new TotalPayoutInfo(2100, 5000, 8000));
|
||||
const totalHeldAndPaid = new TotalHeldAndPaid([paystub]);
|
||||
totalHeldAndPaid.setCurrentMonthEarnings(40000);
|
||||
|
||||
await store.commit(PAYOUT_MUTATIONS.SET_TOTAL, totalHeldAndPaid);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
|
||||
totalHeldAndPaid.held = 400000;
|
||||
|
||||
await store.commit(PAYOUT_MUTATIONS.SET_TOTAL, totalHeldAndPaid);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
@ -20,37 +20,53 @@ exports[`HeldHistoryAllStatsTable renders correctly with actual values 1`] = `
|
||||
<div class="held-history-table-container--large__info-area">
|
||||
<div class="justify-start column-1">
|
||||
<p class="held-history-table-container--large__info-area__text">name1</p>
|
||||
<p class="held-history-table-container--large__info-area__months">1 month</p>
|
||||
<p class="held-history-table-container--large__info-area__months">9 month</p>
|
||||
</div>
|
||||
<div class="column justify-end column-2">
|
||||
<p class="held-history-table-container--large__info-area__text">2020-01-30</p>
|
||||
</div>
|
||||
<div class="column justify-end column-3">
|
||||
<p class="held-history-table-container--large__info-area__text">$0.05</p>
|
||||
<p class="held-history-table-container--large__info-area__text">$0.00</p>
|
||||
</div>
|
||||
<div class="column justify-end column-4">
|
||||
<p class="held-history-table-container--large__info-area__text">$0.02</p>
|
||||
<p class="held-history-table-container--large__info-area__text">$0.00</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="held-history-table-container--large__info-area">
|
||||
<div class="justify-start column-1">
|
||||
<p class="held-history-table-container--large__info-area__text">name2</p>
|
||||
<p class="held-history-table-container--large__info-area__months">5 month</p>
|
||||
<p class="held-history-table-container--large__info-area__months">9 month</p>
|
||||
</div>
|
||||
<div class="column justify-end column-2">
|
||||
<p class="held-history-table-container--large__info-area__text">2020-01-30</p>
|
||||
</div>
|
||||
<div class="column justify-end column-3">
|
||||
<p class="held-history-table-container--large__info-area__text">$0.04</p>
|
||||
<p class="held-history-table-container--large__info-area__text">$0.00</p>
|
||||
</div>
|
||||
<div class="column justify-end column-4">
|
||||
<p class="held-history-table-container--large__info-area__text">$0.03</p>
|
||||
<p class="held-history-table-container--large__info-area__text">$0.00</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="held-history-table-container--large__info-area">
|
||||
<div class="justify-start column-1">
|
||||
<p class="held-history-table-container--large__info-area__text">name3</p>
|
||||
<p class="held-history-table-container--large__info-area__months">9 month</p>
|
||||
</div>
|
||||
<div class="column justify-end column-2">
|
||||
<p class="held-history-table-container--large__info-area__text">2020-01-30</p>
|
||||
</div>
|
||||
<div class="column justify-end column-3">
|
||||
<p class="held-history-table-container--large__info-area__text">$7.85</p>
|
||||
</div>
|
||||
<div class="column justify-end column-4">
|
||||
<p class="held-history-table-container--large__info-area__text">$0.00</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="held-history-table-container--small">
|
||||
<heldhistoryallstatstableitemsmall-stub heldhistoryitem="[object Object]"></heldhistoryallstatstableitemsmall-stub>
|
||||
<heldhistoryallstatstableitemsmall-stub heldhistoryitem="[object Object]"></heldhistoryallstatstableitemsmall-stub>
|
||||
<heldhistoryallstatstableitemsmall-stub heldhistoryitem="[object Object]"></heldhistoryallstatstableitemsmall-stub>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
@ -5,7 +5,7 @@ exports[`HeldHistoryAllStatsTableItemSmall renders correctly with actual values
|
||||
<div class="held-history-table-container--small__item__satellite-info">
|
||||
<div>
|
||||
<p class="held-history-table-container--small__item__satellite-info__name">name1</p>
|
||||
<p class="held-history-table-container--small__item__satellite-info__months">7 month</p>
|
||||
<p class="held-history-table-container--small__item__satellite-info__months">9 month</p>
|
||||
</div>
|
||||
<div class="held-history-table-container--small__item__satellite-info__button">
|
||||
<div class="icon expand">
|
||||
@ -24,7 +24,7 @@ exports[`HeldHistoryAllStatsTableItemSmall renders correctly with actual values
|
||||
<div class="held-history-table-container--small__item__satellite-info">
|
||||
<div>
|
||||
<p class="held-history-table-container--small__item__satellite-info__name">name1</p>
|
||||
<p class="held-history-table-container--small__item__satellite-info__months">7 month</p>
|
||||
<p class="held-history-table-container--small__item__satellite-info__months">9 month</p>
|
||||
</div>
|
||||
<div class="held-history-table-container--small__item__satellite-info__button">
|
||||
<div class="icon hide">
|
||||
@ -40,11 +40,11 @@ exports[`HeldHistoryAllStatsTableItemSmall renders correctly with actual values
|
||||
</div>
|
||||
<div class="held-history-table-container--small__item__held-info__item">
|
||||
<p class="held-history-table-container--small__item__held-info__item__label">Held Total</p>
|
||||
<p class="held-history-table-container--small__item__held-info__item__value">$0.04</p>
|
||||
<p class="held-history-table-container--small__item__held-info__item__value">$7.85</p>
|
||||
</div>
|
||||
<div class="held-history-table-container--small__item__held-info__item">
|
||||
<p class="held-history-table-container--small__item__held-info__item__label">Held Returned</p>
|
||||
<p class="held-history-table-container--small__item__held-info__item__value">$0.01</p>
|
||||
<p class="held-history-table-container--small__item__held-info__item__value">$0.76</p>
|
||||
</div>
|
||||
</div>
|
||||
</transition-stub>
|
||||
@ -56,7 +56,7 @@ exports[`HeldHistoryAllStatsTableItemSmall renders correctly with actual values
|
||||
<div class="held-history-table-container--small__item__satellite-info">
|
||||
<div>
|
||||
<p class="held-history-table-container--small__item__satellite-info__name">name1</p>
|
||||
<p class="held-history-table-container--small__item__satellite-info__months">7 month</p>
|
||||
<p class="held-history-table-container--small__item__satellite-info__months">9 month</p>
|
||||
</div>
|
||||
<div class="held-history-table-container--small__item__satellite-info__button">
|
||||
<div class="icon expand">
|
||||
|
@ -20,13 +20,13 @@ exports[`HeldHistoryMonthlyBreakdownTable renders correctly with actual values 1
|
||||
<div class="held-history-table-container--large__info-area">
|
||||
<div class="justify-start column-1">
|
||||
<p class="held-history-table-container--large__info-area__text">name1</p>
|
||||
<p class="held-history-table-container--large__info-area__months">1 month</p>
|
||||
<p class="held-history-table-container--large__info-area__months">8 month</p>
|
||||
</div>
|
||||
<div class="column justify-end column-2">
|
||||
<p class="held-history-table-container--large__info-area__text">$0.05</p>
|
||||
<p class="held-history-table-container--large__info-area__text">$0.00</p>
|
||||
</div>
|
||||
<div class="column justify-end column-3">
|
||||
<p class="held-history-table-container--large__info-area__text">$0.00</p>
|
||||
<p class="held-history-table-container--large__info-area__text">$0.05</p>
|
||||
</div>
|
||||
<div class="column justify-end column-4">
|
||||
<p class="held-history-table-container--large__info-area__text">$0.00</p>
|
||||
@ -35,31 +35,31 @@ exports[`HeldHistoryMonthlyBreakdownTable renders correctly with actual values 1
|
||||
<div class="held-history-table-container--large__info-area">
|
||||
<div class="justify-start column-1">
|
||||
<p class="held-history-table-container--large__info-area__text">name2</p>
|
||||
<p class="held-history-table-container--large__info-area__months">5 month</p>
|
||||
<p class="held-history-table-container--large__info-area__months">8 month</p>
|
||||
</div>
|
||||
<div class="column justify-end column-2">
|
||||
<p class="held-history-table-container--large__info-area__text">$0.05</p>
|
||||
<p class="held-history-table-container--large__info-area__text">$0.00</p>
|
||||
</div>
|
||||
<div class="column justify-end column-3">
|
||||
<p class="held-history-table-container--large__info-area__text">$0.42</p>
|
||||
<p class="held-history-table-container--large__info-area__text">$0.05</p>
|
||||
</div>
|
||||
<div class="column justify-end column-4">
|
||||
<p class="held-history-table-container--large__info-area__text">$0.00</p>
|
||||
<p class="held-history-table-container--large__info-area__text">$0.42</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="held-history-table-container--large__info-area">
|
||||
<div class="justify-start column-1">
|
||||
<p class="held-history-table-container--large__info-area__text">name3</p>
|
||||
<p class="held-history-table-container--large__info-area__months">6 month</p>
|
||||
<p class="held-history-table-container--large__info-area__months">8 month</p>
|
||||
</div>
|
||||
<div class="column justify-end column-2">
|
||||
<p class="held-history-table-container--large__info-area__text">$0.05</p>
|
||||
<p class="held-history-table-container--large__info-area__text">$0.00</p>
|
||||
</div>
|
||||
<div class="column justify-end column-3">
|
||||
<p class="held-history-table-container--large__info-area__text">$7.33</p>
|
||||
<p class="held-history-table-container--large__info-area__text">$0.05</p>
|
||||
</div>
|
||||
<div class="column justify-end column-4">
|
||||
<p class="held-history-table-container--large__info-area__text">$7.85</p>
|
||||
<p class="held-history-table-container--large__info-area__text">$7.33</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -5,7 +5,7 @@ exports[`HeldHistoryMonthlyBreakdownTableSmall renders correctly with actual val
|
||||
<div class="held-history-table-container--small__item__satellite-info">
|
||||
<div>
|
||||
<p class="held-history-table-container--small__item__satellite-info__name">name1</p>
|
||||
<p class="held-history-table-container--small__item__satellite-info__months">6 month</p>
|
||||
<p class="held-history-table-container--small__item__satellite-info__months">8 month</p>
|
||||
</div>
|
||||
<div class="held-history-table-container--small__item__satellite-info__button">
|
||||
<div class="icon expand">
|
||||
@ -24,7 +24,7 @@ exports[`HeldHistoryMonthlyBreakdownTableSmall renders correctly with actual val
|
||||
<div class="held-history-table-container--small__item__satellite-info">
|
||||
<div>
|
||||
<p class="held-history-table-container--small__item__satellite-info__name">name1</p>
|
||||
<p class="held-history-table-container--small__item__satellite-info__months">6 month</p>
|
||||
<p class="held-history-table-container--small__item__satellite-info__months">8 month</p>
|
||||
</div>
|
||||
<div class="held-history-table-container--small__item__satellite-info__button">
|
||||
<div class="icon hide">
|
||||
@ -36,15 +36,15 @@ exports[`HeldHistoryMonthlyBreakdownTableSmall renders correctly with actual val
|
||||
<div class="held-history-table-container--small__item__held-info">
|
||||
<div class="held-history-table-container--small__item__held-info__item">
|
||||
<p class="held-history-table-container--small__item__held-info__item__label">Month 1-3</p>
|
||||
<p class="held-history-table-container--small__item__held-info__item__value">$0.05</p>
|
||||
<p class="held-history-table-container--small__item__held-info__item__value">$0.00</p>
|
||||
</div>
|
||||
<div class="held-history-table-container--small__item__held-info__item">
|
||||
<p class="held-history-table-container--small__item__held-info__item__label">Month 4-6</p>
|
||||
<p class="held-history-table-container--small__item__held-info__item__value">$7.33</p>
|
||||
<p class="held-history-table-container--small__item__held-info__item__value">$0.05</p>
|
||||
</div>
|
||||
<div class="held-history-table-container--small__item__held-info__item">
|
||||
<p class="held-history-table-container--small__item__held-info__item__label">Month 7-9</p>
|
||||
<p class="held-history-table-container--small__item__held-info__item__value">$7.85</p>
|
||||
<p class="held-history-table-container--small__item__held-info__item__value">$7.33</p>
|
||||
</div>
|
||||
</div>
|
||||
</transition-stub>
|
||||
@ -56,7 +56,7 @@ exports[`HeldHistoryMonthlyBreakdownTableSmall renders correctly with actual val
|
||||
<div class="held-history-table-container--small__item__satellite-info">
|
||||
<div>
|
||||
<p class="held-history-table-container--small__item__satellite-info__name">name1</p>
|
||||
<p class="held-history-table-container--small__item__satellite-info__months">6 month</p>
|
||||
<p class="held-history-table-container--small__item__satellite-info__months">8 month</p>
|
||||
</div>
|
||||
<div class="held-history-table-container--small__item__satellite-info__button">
|
||||
<div class="icon expand">
|
||||
|
@ -76,7 +76,9 @@ exports[`PayoutHistoryTableItem renders correctly with actual values 2`] = `
|
||||
</div>
|
||||
<div class="payout-history-item__expanded-area__right-area__divider"></div>
|
||||
<div class="payout-history-item__expanded-area__right-area__footer">
|
||||
<div class="payout-history-item__expanded-area__right-area__footer__transaction"><a href="receipt1" target="_blank" rel="noreferrer noopener">Transaction</a>
|
||||
<div class="payout-history-item__expanded-area__right-area__footer__transaction"><a href="receipt1" target="_blank" rel="noreferrer noopener" class="payout-history-item__expanded-area__right-area__footer__transaction__link">
|
||||
Transaction
|
||||
</a>
|
||||
<shareicon-stub class="payout-history-item__expanded-area__right-area__footer__transaction__icon"></shareicon-stub>
|
||||
</div>
|
||||
<p class="payout-history-item__expanded-area__right-area__footer__total">$0.80</p>
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`TotalPayoutInfo renders correctly 1`] = `
|
||||
exports[`TotalPayoutArea renders correctly 1`] = `
|
||||
<section class="total-payout-area">
|
||||
<div class="total-payout-area__united-info-area">
|
||||
<div class="total-payout-area__united-info-area__item">
|
||||
@ -24,26 +24,50 @@ exports[`TotalPayoutInfo renders correctly 1`] = `
|
||||
</section>
|
||||
`;
|
||||
|
||||
exports[`TotalPayoutInfo renders correctly with actual values 1`] = `
|
||||
exports[`TotalPayoutArea renders correctly with actual values 1`] = `
|
||||
<section class="total-payout-area">
|
||||
<div class="total-payout-area__united-info-area">
|
||||
<div class="total-payout-area__united-info-area__item">
|
||||
<p class="total-payout-area__united-info-area__item__label">Current Month Earnings</p>
|
||||
<p class="total-payout-area__united-info-area__item__amount">$80.00</p>
|
||||
<p class="total-payout-area__united-info-area__item__amount">$400.00</p>
|
||||
</div>
|
||||
<div class="total-payout-area__united-info-area__item align-center">
|
||||
<p class="total-payout-area__united-info-area__item__label">Total Earned</p>
|
||||
<p class="total-payout-area__united-info-area__item__amount">$50.00</p>
|
||||
<p class="total-payout-area__united-info-area__item__amount">$1.00</p>
|
||||
</div>
|
||||
<div class="total-payout-area__united-info-area__item align-end">
|
||||
<p class="total-payout-area__united-info-area__item__label">Total Held Amount</p>
|
||||
<p class="total-payout-area__united-info-area__item__amount">$21.00</p>
|
||||
<p class="total-payout-area__united-info-area__item__amount">$0.50</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="total-payout-area__info-area">
|
||||
<singleinfo-stub width="100%" label="Current Month Earnings" value="$80.00"></singleinfo-stub>
|
||||
<singleinfo-stub width="100%" label="Total Earnings" value="$50.00"></singleinfo-stub>
|
||||
<singleinfo-stub width="100%" label="Total Held Amount" value="$21.00"></singleinfo-stub>
|
||||
<singleinfo-stub width="100%" label="Current Month Earnings" value="$400.00"></singleinfo-stub>
|
||||
<singleinfo-stub width="100%" label="Total Earnings" value="$1.00"></singleinfo-stub>
|
||||
<singleinfo-stub width="100%" label="Total Held Amount" value="$0.50"></singleinfo-stub>
|
||||
</div>
|
||||
</section>
|
||||
`;
|
||||
|
||||
exports[`TotalPayoutArea renders correctly with actual values 2`] = `
|
||||
<section class="total-payout-area">
|
||||
<div class="total-payout-area__united-info-area">
|
||||
<div class="total-payout-area__united-info-area__item">
|
||||
<p class="total-payout-area__united-info-area__item__label">Current Month Earnings</p>
|
||||
<p class="total-payout-area__united-info-area__item__amount">$400.00</p>
|
||||
</div>
|
||||
<div class="total-payout-area__united-info-area__item align-center">
|
||||
<p class="total-payout-area__united-info-area__item__label">Total Earned</p>
|
||||
<p class="total-payout-area__united-info-area__item__amount">$1.00</p>
|
||||
</div>
|
||||
<div class="total-payout-area__united-info-area__item align-end">
|
||||
<p class="total-payout-area__united-info-area__item__label">Total Held Amount</p>
|
||||
<p class="total-payout-area__united-info-area__item__amount">$4000.00</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="total-payout-area__info-area">
|
||||
<singleinfo-stub width="100%" label="Current Month Earnings" value="$400.00"></singleinfo-stub>
|
||||
<singleinfo-stub width="100%" label="Total Earnings" value="$1.00"></singleinfo-stub>
|
||||
<singleinfo-stub width="100%" label="Total Held Amount" value="$4000.00"></singleinfo-stub>
|
||||
</div>
|
||||
</section>
|
||||
`;
|
||||
|
@ -5,26 +5,27 @@ 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,
|
||||
HeldHistoryAllStatItem,
|
||||
HeldHistoryMonthlyBreakdownItem,
|
||||
HeldInfo,
|
||||
PayoutHistoryItem,
|
||||
PayoutInfoRange,
|
||||
PayoutPeriod,
|
||||
PreviousMonthEstimatedPayout,
|
||||
TotalPayoutInfo,
|
||||
} from '@/app/types/payout';
|
||||
import { PayoutInfoRange } from '@/app/types/payout';
|
||||
import { getHeldPercentage, getMonthsBeforeNow } from '@/app/utils/payout';
|
||||
import { PayoutHttpApi } from '@/storagenode/api/payout';
|
||||
import { SNOApi } from '@/storagenode/api/storagenode';
|
||||
import {
|
||||
EstimatedPayout,
|
||||
PayoutPeriod,
|
||||
Paystub,
|
||||
PreviousMonthEstimatedPayout,
|
||||
SatelliteHeldHistory,
|
||||
SatellitePayoutForPeriod,
|
||||
TotalHeldAndPaid,
|
||||
TotalPaystubForPeriod,
|
||||
} from '@/storagenode/payouts/payouts';
|
||||
import { PayoutService } from '@/storagenode/payouts/service';
|
||||
import { createLocalVue } from '@vue/test-utils';
|
||||
|
||||
const Vue = createLocalVue();
|
||||
const payoutApi = new PayoutHttpApi();
|
||||
const payoutModule = makePayoutModule(payoutApi);
|
||||
const payoutService = new PayoutService(payoutApi);
|
||||
const payoutModule = makePayoutModule(payoutApi, payoutService);
|
||||
|
||||
const nodeApi = new SNOApi();
|
||||
const nodeModule = makeNodeModule(nodeApi);
|
||||
@ -40,23 +41,29 @@ describe('mutations', (): void => {
|
||||
createLocalVue().use(Vuex);
|
||||
});
|
||||
|
||||
it('sets held information', (): void => {
|
||||
const heldInfo = new HeldInfo(13, 12, 11);
|
||||
it('sets payout information', (): void => {
|
||||
const totalPaystubForPeriod = new TotalPaystubForPeriod([new Paystub(13, 12, 11)]);
|
||||
|
||||
store.commit(PAYOUT_MUTATIONS.SET_HELD_INFO, heldInfo);
|
||||
store.commit(PAYOUT_MUTATIONS.SET_PAYOUT_INFO, totalPaystubForPeriod);
|
||||
|
||||
expect(state.payoutModule.heldInfo.usageAtRest).toBe(13);
|
||||
expect(state.payoutModule.heldInfo.usageGet).toBe(12);
|
||||
expect(state.payoutModule.heldInfo.usagePut).toBe(11);
|
||||
expect(state.payoutModule.totalPaystubForPeriod.usageAtRest).toBe(13);
|
||||
expect(state.payoutModule.totalPaystubForPeriod.usageGet).toBe(12);
|
||||
expect(state.payoutModule.totalPaystubForPeriod.usagePut).toBe(11);
|
||||
});
|
||||
|
||||
it('sets total payout information', (): void => {
|
||||
const totalInfo = new TotalPayoutInfo(50, 100, 22);
|
||||
const paystub = new Paystub();
|
||||
paystub.held = 600000;
|
||||
paystub.disposed = 100000;
|
||||
paystub.paid = 1000000;
|
||||
|
||||
store.commit(PAYOUT_MUTATIONS.SET_TOTAL, totalInfo);
|
||||
const totalHeldAndPaid = new TotalHeldAndPaid([paystub]);
|
||||
totalHeldAndPaid.setCurrentMonthEarnings(22);
|
||||
|
||||
expect(state.payoutModule.totalHeldAmount).toBe(50);
|
||||
expect(state.payoutModule.totalEarnings).toBe(100);
|
||||
store.commit(PAYOUT_MUTATIONS.SET_TOTAL, totalHeldAndPaid);
|
||||
|
||||
expect(state.payoutModule.totalHeldAndPaid.held).toBe(50);
|
||||
expect(state.payoutModule.totalHeldAndPaid.paid).toBe(100);
|
||||
expect(state.payoutModule.currentMonthEarnings).toBe(22);
|
||||
});
|
||||
|
||||
@ -84,25 +91,18 @@ describe('mutations', (): void => {
|
||||
it('sets held history', (): void => {
|
||||
const testJoinAt = new Date(Date.UTC(2020, 0, 30));
|
||||
|
||||
const testHeldHistory = new HeldHistory(
|
||||
[
|
||||
new HeldHistoryMonthlyBreakdownItem('1', 'name1', 1, 50000, 0, 0),
|
||||
new HeldHistoryMonthlyBreakdownItem('2', 'name2', 5, 50000, 422280, 0),
|
||||
new HeldHistoryMonthlyBreakdownItem('3', 'name3', 6, 50000, 7333880, 7852235),
|
||||
],
|
||||
[
|
||||
new HeldHistoryAllStatItem('1', 'name1', 1, 1000000, 0, testJoinAt),
|
||||
new HeldHistoryAllStatItem('2', 'name2', 5, 300000, 20, testJoinAt),
|
||||
],
|
||||
);
|
||||
const testHeldHistory = [
|
||||
new SatelliteHeldHistory('1', 'name1', 1, 50000, 0, 0, 1, testJoinAt),
|
||||
new SatelliteHeldHistory('2', 'name2', 5, 50000, 422280, 0),
|
||||
new SatelliteHeldHistory('3', 'name3', 6, 50000, 7333880, 7852235),
|
||||
];
|
||||
|
||||
store.commit(PAYOUT_MUTATIONS.SET_HELD_HISTORY, testHeldHistory);
|
||||
|
||||
expect(state.payoutModule.heldHistory.monthlyBreakdown.length).toBe(testHeldHistory.monthlyBreakdown.length);
|
||||
expect(state.payoutModule.heldHistory.monthlyBreakdown[1].satelliteName).toBe(testHeldHistory.monthlyBreakdown[1].satelliteName);
|
||||
expect(state.payoutModule.heldHistory.allStats.length).toBe(testHeldHistory.allStats.length);
|
||||
expect(state.payoutModule.heldHistory.allStats[0].joinedAt).toBe(testJoinAt);
|
||||
expect(state.payoutModule.heldHistory.allStats[1].totalHeld).toBe(30);
|
||||
expect(state.payoutModule.heldHistory.length).toBe(testHeldHistory.length);
|
||||
expect(state.payoutModule.heldHistory[1].satelliteName).toBe(testHeldHistory[1].satelliteName);
|
||||
expect(state.payoutModule.heldHistory[0].joinedAt).toBe(testJoinAt);
|
||||
expect(state.payoutModule.heldHistory[2].totalHeld).toBe(785.2235);
|
||||
});
|
||||
|
||||
it('sets estimated payout information', (): void => {
|
||||
@ -159,10 +159,10 @@ describe('mutations', (): void => {
|
||||
|
||||
it('sets payout history period', (): void => {
|
||||
const payoutHistory = [
|
||||
new PayoutHistoryItem('1', 'name1', 1, 10, 120, 140,
|
||||
new SatellitePayoutForPeriod('1', 'name1', 1, 10, 120, 140,
|
||||
50, 60, 20, 80, 'receipt1', false,
|
||||
),
|
||||
new PayoutHistoryItem('2', 'name2', 16, 10, 120, 140,
|
||||
new SatellitePayoutForPeriod('2', 'name2', 16, 10, 120, 140,
|
||||
50, 60, 20, 80, 'receipt2', true,
|
||||
),
|
||||
];
|
||||
@ -179,82 +179,94 @@ describe('actions', () => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
it('success get held info by month', async (): Promise<void> => {
|
||||
jest.spyOn(payoutApi, 'getHeldInfoByMonth').mockReturnValue(
|
||||
Promise.resolve(new HeldInfo(1, 2 , 3, 4, 5)),
|
||||
it('success get payout info by month', async (): Promise<void> => {
|
||||
const paystub = new Paystub();
|
||||
paystub.usagePut = 3;
|
||||
paystub.held = 100000;
|
||||
|
||||
jest.spyOn(payoutApi, 'getPaystubsForPeriod').mockReturnValue(
|
||||
Promise.resolve([paystub]),
|
||||
);
|
||||
|
||||
const range = new PayoutInfoRange(null, new PayoutPeriod(2020, 3));
|
||||
|
||||
store.commit(PAYOUT_MUTATIONS.SET_RANGE, range);
|
||||
|
||||
await store.dispatch(PAYOUT_ACTIONS.GET_HELD_INFO);
|
||||
await store.dispatch(PAYOUT_ACTIONS.GET_PAYOUT_INFO);
|
||||
|
||||
expect(state.payoutModule.heldInfo.usagePut).toBe(3);
|
||||
expect(state.payoutModule.heldInfo.held).toBe(0);
|
||||
expect(state.payoutModule.totalPaystubForPeriod.usagePut).toBe(3);
|
||||
expect(state.payoutModule.totalPaystubForPeriod.held).toBe(10);
|
||||
expect(state.payoutModule.heldPercentage).toBe(getHeldPercentage(new Date()));
|
||||
});
|
||||
|
||||
it('get held info by month throws an error when api call fails', async (): Promise<void> => {
|
||||
jest.spyOn(payoutApi, 'getHeldInfoByMonth').mockImplementation(() => { throw new Error(); });
|
||||
it('get payout info by month throws an error when api call fails', async (): Promise<void> => {
|
||||
jest.spyOn(payoutApi, 'getPaystubsForPeriod').mockImplementation(() => { throw new Error(); });
|
||||
|
||||
try {
|
||||
await store.dispatch(PAYOUT_ACTIONS.GET_HELD_INFO);
|
||||
await store.dispatch(PAYOUT_ACTIONS.GET_PAYOUT_INFO);
|
||||
expect(true).toBe(false);
|
||||
} catch (error) {
|
||||
expect(state.payoutModule.heldInfo.usagePut).toBe(3);
|
||||
expect(state.payoutModule.heldInfo.held).toBe(0);
|
||||
expect(state.payoutModule.totalPaystubForPeriod.usagePut).toBe(3);
|
||||
expect(state.payoutModule.totalPaystubForPeriod.held).toBe(10);
|
||||
}
|
||||
});
|
||||
|
||||
it('success get held info by period', async (): Promise<void> => {
|
||||
jest.spyOn(payoutApi, 'getHeldInfoByPeriod').mockReturnValue(
|
||||
Promise.resolve(new HeldInfo(1, 2 , 3, 4, 5)),
|
||||
it('success get payout info by period', async (): Promise<void> => {
|
||||
const paystub = new Paystub();
|
||||
paystub.usagePut = 3;
|
||||
paystub.held = 100000;
|
||||
|
||||
jest.spyOn(payoutApi, 'getPaystubsForPeriod').mockReturnValue(
|
||||
Promise.resolve([paystub]),
|
||||
);
|
||||
|
||||
const range = new PayoutInfoRange(new PayoutPeriod(2019, 2), new PayoutPeriod(2020, 3));
|
||||
|
||||
store.commit(PAYOUT_MUTATIONS.SET_RANGE, range);
|
||||
|
||||
await store.dispatch(PAYOUT_ACTIONS.GET_HELD_INFO);
|
||||
await store.dispatch(PAYOUT_ACTIONS.GET_PAYOUT_INFO);
|
||||
|
||||
expect(state.payoutModule.heldInfo.usagePut).toBe(3);
|
||||
expect(state.payoutModule.heldInfo.held).toBe(0);
|
||||
expect(state.payoutModule.totalPaystubForPeriod.usagePut).toBe(3);
|
||||
expect(state.payoutModule.totalPaystubForPeriod.held).toBe(10);
|
||||
});
|
||||
|
||||
it('get held info by period throws an error when api call fails', async (): Promise<void> => {
|
||||
jest.spyOn(payoutApi, 'getHeldInfoByPeriod').mockImplementation(() => { throw new Error(); });
|
||||
it('get payout info by period throws an error when api call fails', async (): Promise<void> => {
|
||||
jest.spyOn(payoutApi, 'getPaystubsForPeriod').mockImplementation(() => { throw new Error(); });
|
||||
|
||||
try {
|
||||
await store.dispatch(PAYOUT_ACTIONS.GET_HELD_INFO);
|
||||
await store.dispatch(PAYOUT_ACTIONS.GET_PAYOUT_INFO);
|
||||
expect(true).toBe(false);
|
||||
} catch (error) {
|
||||
expect(state.payoutModule.heldInfo.usagePut).toBe(3);
|
||||
expect(state.payoutModule.heldInfo.held).toBe(0);
|
||||
expect(state.payoutModule.totalPaystubForPeriod.usagePut).toBe(3);
|
||||
expect(state.payoutModule.totalPaystubForPeriod.held).toBe(10);
|
||||
}
|
||||
});
|
||||
|
||||
it('success get total', async (): Promise<void> => {
|
||||
jest.spyOn(payoutApi, 'getTotal').mockReturnValue(
|
||||
Promise.resolve(new TotalPayoutInfo(10, 20, 5)),
|
||||
const paystub = new Paystub();
|
||||
paystub.held = 100000;
|
||||
paystub.paid = 200000;
|
||||
|
||||
jest.spyOn(payoutApi, 'getPaystubsForPeriod').mockReturnValue(
|
||||
Promise.resolve([paystub]),
|
||||
);
|
||||
|
||||
await store.dispatch(PAYOUT_ACTIONS.GET_TOTAL);
|
||||
|
||||
expect(state.payoutModule.totalHeldAmount).toBe(10);
|
||||
expect(state.payoutModule.totalEarnings).toBe(20);
|
||||
expect(state.payoutModule.totalHeldAndPaid.held).toBe(10);
|
||||
expect(state.payoutModule.totalHeldAndPaid.paid).toBe(20);
|
||||
expect(state.payoutModule.currentMonthEarnings).toBe(0);
|
||||
});
|
||||
|
||||
it('get total throws an error when api call fails', async (): Promise<void> => {
|
||||
jest.spyOn(payoutApi, 'getTotal').mockImplementation(() => { throw new Error(); });
|
||||
jest.spyOn(payoutApi, 'getPaystubsForPeriod').mockImplementation(() => { throw new Error(); });
|
||||
|
||||
try {
|
||||
await store.dispatch(PAYOUT_ACTIONS.GET_TOTAL);
|
||||
expect(true).toBe(false);
|
||||
} catch (error) {
|
||||
expect(state.payoutModule.totalHeldAmount).toBe(10);
|
||||
expect(state.payoutModule.totalEarnings).toBe(20);
|
||||
expect(state.payoutModule.totalHeldAndPaid.held).toBe(10);
|
||||
expect(state.payoutModule.totalHeldAndPaid.paid).toBe(20);
|
||||
expect(state.payoutModule.currentMonthEarnings).toBe(0);
|
||||
}
|
||||
});
|
||||
@ -290,28 +302,22 @@ describe('actions', () => {
|
||||
|
||||
it('success get held history', async (): Promise<void> => {
|
||||
const testJoinAt = new Date(Date.UTC(2020, 0, 30));
|
||||
const testHeldHistory = [
|
||||
new SatelliteHeldHistory('1', 'name1', 1, 50000, 0, 0, 1, testJoinAt),
|
||||
new SatelliteHeldHistory('2', 'name2', 5, 50000, 422280, 0),
|
||||
new SatelliteHeldHistory('3', 'name3', 6, 50000, 7333880, 7852235),
|
||||
];
|
||||
|
||||
jest.spyOn(payoutApi, 'getHeldHistory').mockReturnValue(
|
||||
Promise.resolve(new HeldHistory(
|
||||
[
|
||||
new HeldHistoryMonthlyBreakdownItem('1', 'name1', 1, 50000, 0, 0),
|
||||
new HeldHistoryMonthlyBreakdownItem('2', 'name2', 5, 50000, 422280, 0),
|
||||
new HeldHistoryMonthlyBreakdownItem('3', 'name3', 6, 50000, 7333880, 7852235),
|
||||
],
|
||||
[
|
||||
new HeldHistoryAllStatItem('1', 'name1', 1, 100, 0, testJoinAt),
|
||||
new HeldHistoryAllStatItem('2', 'name2', 5, 300000, 20, testJoinAt),
|
||||
],
|
||||
)),
|
||||
Promise.resolve(testHeldHistory),
|
||||
);
|
||||
|
||||
await store.dispatch(PAYOUT_ACTIONS.GET_HELD_HISTORY);
|
||||
|
||||
expect(state.payoutModule.heldHistory.monthlyBreakdown.length).toBe(3);
|
||||
expect(state.payoutModule.heldHistory.monthlyBreakdown[1].satelliteName).toBe('name2');
|
||||
expect(state.payoutModule.heldHistory.allStats.length).toBe(2);
|
||||
expect(state.payoutModule.heldHistory.allStats[0].joinedAt).toBe(testJoinAt);
|
||||
expect(state.payoutModule.heldHistory.allStats[1].totalHeld).toBe(30);
|
||||
expect(state.payoutModule.heldHistory.length).toBe(3);
|
||||
expect(state.payoutModule.heldHistory[1].satelliteName).toBe('name2');
|
||||
expect(state.payoutModule.heldHistory[0].joinedAt).toBe(testJoinAt);
|
||||
expect(state.payoutModule.heldHistory[2].totalHeld).toBe(785.2235);
|
||||
});
|
||||
|
||||
it('get total throws an error when api call fails', async (): Promise<void> => {
|
||||
@ -321,8 +327,7 @@ describe('actions', () => {
|
||||
await store.dispatch(PAYOUT_ACTIONS.GET_HELD_HISTORY);
|
||||
expect(true).toBe(false);
|
||||
} catch (error) {
|
||||
expect(state.payoutModule.heldHistory.monthlyBreakdown.length).toBe(3);
|
||||
expect(state.payoutModule.heldHistory.monthlyBreakdown[1].satelliteName).toBe('name2');
|
||||
expect(state.payoutModule.heldHistory.length).toBe(3);
|
||||
}
|
||||
});
|
||||
|
||||
@ -349,7 +354,7 @@ describe('actions', () => {
|
||||
it('success get payout history', async (): Promise<void> => {
|
||||
jest.spyOn(payoutApi, 'getPayoutHistory').mockReturnValue(
|
||||
Promise.resolve([
|
||||
new PayoutHistoryItem('1', 'name1', 1, 100000, 2200000, 140,
|
||||
new SatellitePayoutForPeriod('1', 'name1', 1, 100000, 2200000, 140,
|
||||
500000, 600000, 200000, 800000, 'receipt1', false,
|
||||
),
|
||||
]),
|
||||
@ -367,10 +372,10 @@ describe('getters', () => {
|
||||
it('getter totalPaidForPayoutHistoryPeriod returns correct value', async (): Promise<void> => {
|
||||
jest.spyOn(payoutApi, 'getPayoutHistory').mockReturnValue(
|
||||
Promise.resolve([
|
||||
new PayoutHistoryItem('1', 'name1', 1, 10, 120, 140,
|
||||
new SatellitePayoutForPeriod('1', 'name1', 1, 10, 120, 140,
|
||||
50, 60, 20, 1300000, 'receipt1', false,
|
||||
),
|
||||
new PayoutHistoryItem('2', 'name2', 16, 10, 120, 140,
|
||||
new SatellitePayoutForPeriod('2', 'name2', 16, 10, 120, 140,
|
||||
50, 60, 20, 1700000, 'receipt2', true,
|
||||
),
|
||||
]),
|
||||
@ -382,7 +387,7 @@ describe('getters', () => {
|
||||
});
|
||||
|
||||
it('get estimated payout information throws an error when api call fails', async (): Promise<void> => {
|
||||
jest.spyOn(payoutApi, 'getEstimatedInfo').mockImplementation(() => { throw new Error(); });
|
||||
jest.spyOn(payoutApi, 'getEstimatedPayout').mockImplementation(() => { throw new Error(); });
|
||||
|
||||
try {
|
||||
await store.dispatch(PAYOUT_ACTIONS.GET_ESTIMATION);
|
||||
@ -394,7 +399,7 @@ describe('getters', () => {
|
||||
});
|
||||
|
||||
it('success get estimated payout information', async (): Promise<void> => {
|
||||
jest.spyOn(payoutApi, 'getEstimatedInfo').mockReturnValue(
|
||||
jest.spyOn(payoutApi, 'getEstimatedPayout').mockReturnValue(
|
||||
Promise.resolve(new EstimatedPayout(
|
||||
new PreviousMonthEstimatedPayout(
|
||||
1,
|
||||
|
Loading…
Reference in New Issue
Block a user