Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Export Hosted Collectives: add contributionRefundedTotal and refact average resolvers #582

Merged
merged 3 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 27 additions & 18 deletions src/graphql/schemaV2.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -9600,36 +9600,45 @@ Return a summary of transaction info about a given account within the context of
"""
type HostedAccountSummary {
expenseCount: Int
expenseTotal: Amount
expenseMaxValue: Amount
expenseDistinctPayee: Int
contributionCount: Int
contributionTotal: Amount
hostFeeTotal: Amount
spentTotal: Amount
receivedTotal: Amount

"""
Average calculated based on the number of months since the first transaction of this kind within the requested time frame
Average calculated over the number of months the collective was approved or the number of months since dateFrom, whichever is less
"""
expenseMonthlyAverageCount: Float
expenseTotal: Amount
expenseAverageTotal(period: AveragePeriod = MONTH): Amount

"""
Average calculated based on the number of months since the first transaction of this kind within the requested time frame
Average calculated over the number of months the collective was approved or the number of months since dateFrom, whichever is less
"""
expenseMonthlyAverageTotal: Amount
expenseMaxValue: Amount
expenseDistinctPayee: Int
contributionCount: Int
expenseAverageCount(period: AveragePeriod = MONTH): Float

"""
Average calculated based on the number of months since the first transaction of this kind within the requested time frame
Average calculated over the number of months the collective was approved or the number of months since dateFrom, whichever is less
"""
contributionMonthlyAverageCount: Float
contributionTotal: Amount
contributionAverageTotal(period: AveragePeriod = MONTH): Amount

"""
Average calculated based on the number of months since the first transaction of this kind within the requested time frame
Average calculated over the number of months/years the collective was approved or the number of months since dateFrom, whichever is less
"""
contributionMonthlyAverageTotal: Amount
hostFeeTotal: Amount
spentTotal: Amount
receivedTotal: Amount
spentTotalMonthlyAverage: Amount
receivedTotalMonthlyAverage: Amount
contributionAverageCount(period: AveragePeriod = MONTH): Float
spentTotalAverage(period: AveragePeriod = MONTH): Amount
receivedTotalAverage(period: AveragePeriod = MONTH): Amount
contributionRefundedTotal: Amount
}

"""
The period over which the average is calculated
"""
enum AveragePeriod {
YEAR
MONTH
}

"""
Expand Down
82 changes: 62 additions & 20 deletions src/server/controllers/hosted-collectives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type Fields =
| 'numberOfPayeesYear'
| 'numberOfContributionsYear'
| 'valueOfContributionsYear'
| 'valueOfRefundedContributionsYear'
| 'valueOfHostFeeYear'
| 'spentTotalYear'
| 'receivedTotalYear'
Expand All @@ -52,6 +53,7 @@ type Fields =
| 'numberOfPayeesAllTime'
| 'numberOfContributionsAllTime'
| 'valueOfContributionsAllTime'
| 'valueOfRefundedContributionsAllTime'
| 'valueOfHostFeeAllTime'
| 'spentTotalAllTime'
| 'receivedTotalAllTime'
Expand All @@ -60,11 +62,28 @@ type Fields =
| 'contributionMonthlyAverageCount'
| 'contributionMonthlyAverageTotal'
| 'spentTotalMonthlyAverage'
| 'receivedTotalMonthlyAverage';
| 'receivedTotalMonthlyAverage'
| 'spentTotalYearlyAverage'
| 'receivedTotalYearlyAverage';

const hostQuery = gqlV2`
query HostedCollectives(
$hostSlug: String!
) {
host(slug: $hostSlug) {
id
legacyId
slug
name
currency
}
}
`;

export const hostedCollectivesQuery = gqlV2`
query HostedCollectives(
$hostSlug: String!
$hostCurrency: Currency!
$limit: Int!
$offset: Int!
$sort: OrderByInput
Expand Down Expand Up @@ -122,7 +141,7 @@ export const hostedCollectivesQuery = gqlV2`
unhostedAt(host: { slug: $hostSlug })
stats {
id
balance {
balance(currency: $hostCurrency) {
value
currency
}
Expand Down Expand Up @@ -159,32 +178,36 @@ export const hostedCollectivesQuery = gqlV2`
}
}
yearSummary: summary(dateFrom: $lastYear) @include(if: $includeYearSummary) {
expenseTotal { valueInCents, value, currency }
expenseTotal { value, currency }
expenseCount
expenseMaxValue { valueInCents, value, currency }
expenseMaxValue { value, currency }
expenseDistinctPayee
contributionCount
contributionTotal { valueInCents, value, currency }
hostFeeTotal { valueInCents, value, currency }
spentTotal { valueInCents, value, currency }
receivedTotal { valueInCents, value, currency }
contributionTotal { value, currency }
contributionRefundedTotal { value, currency }
hostFeeTotal { value, currency }
spentTotal { value, currency }
receivedTotal { value, currency }
}
allTimeSummary: summary @include(if: $includeAllTimeSummary) {
expenseTotal { valueInCents, value, currency }
expenseTotal { value, currency }
expenseCount
expenseMaxValue { valueInCents, value, currency }
expenseMaxValue { value, currency }
expenseDistinctPayee
contributionCount
contributionTotal { valueInCents, value, currency }
hostFeeTotal { valueInCents, value, currency }
spentTotal { valueInCents, value, currency }
receivedTotal { valueInCents, value, currency }
expenseMonthlyAverageCount
expenseMonthlyAverageTotal { valueInCents, value, currency }
contributionMonthlyAverageCount
contributionMonthlyAverageTotal { valueInCents, value, currency }
spentTotalMonthlyAverage { valueInCents, value, currency }
receivedTotalMonthlyAverage { valueInCents, value, currency }
contributionTotal { value, currency }
contributionRefundedTotal { value, currency }
hostFeeTotal { value, currency }
spentTotal { value, currency }
receivedTotal { value, currency }
expenseMonthlyAverageCount: expenseAverageCount(period: MONTH)
expenseMonthlyAverageTotal: expenseAverageTotal(period: MONTH) { value, currency }
contributionMonthlyAverageCount: contributionAverageCount(period: MONTH)
contributionMonthlyAverageTotal: contributionAverageTotal(period: MONTH) { value, currency }
spentTotalMonthlyAverage: spentTotalAverage(period: MONTH) { value, currency }
receivedTotalMonthlyAverage: receivedTotalAverage(period: MONTH) { value, currency }
spentTotalYearlyAverage: spentTotalAverage(period: YEAR) { value, currency }
receivedTotalYearlyAverage: receivedTotalAverage(period: YEAR) { value, currency }
}
}
admins: members(role: [ADMIN]) {
Expand Down Expand Up @@ -281,6 +304,8 @@ const csvMapping: Record<Fields, string | Function> = {
numberOfContributionsYear: (account) => account.yearSummary?.contributionCount,
valueOfContributionsYear: (account) =>
account.yearSummary?.contributionTotal && amountAsString(account.yearSummary.contributionTotal),
valueOfRefundedContributionsYear: (account) =>
account.yearSummary?.contributionRefundedTotal && amountAsString(account.yearSummary.contributionRefundedTotal),
valueOfHostFeeYear: (account) =>
account.yearSummary?.hostFeeTotal && amountAsString(account.yearSummary.hostFeeTotal),
spentTotalYear: (account) => account.yearSummary?.spentTotal && amountAsString(account.yearSummary.spentTotal),
Expand All @@ -295,6 +320,9 @@ const csvMapping: Record<Fields, string | Function> = {
numberOfContributionsAllTime: (account) => account.allTimeSummary?.contributionCount,
valueOfContributionsAllTime: (account) =>
account.allTimeSummary?.contributionTotal && amountAsString(account.allTimeSummary.contributionTotal),
valueOfRefundedContributionsAllTime: (account) =>
account.allTimeSummary?.contributionRefundedTotal &&
amountAsString(account.allTimeSummary.contributionRefundedTotal),
valueOfHostFeeAllTime: (account) =>
account.allTimeSummary?.hostFeeTotal && amountAsString(account.allTimeSummary.hostFeeTotal),
spentTotalAllTime: (account) =>
Expand All @@ -314,6 +342,11 @@ const csvMapping: Record<Fields, string | Function> = {
receivedTotalMonthlyAverage: (account) =>
account.allTimeSummary?.receivedTotalMonthlyAverage &&
amountAsString(account.allTimeSummary.receivedTotalMonthlyAverage),
spentTotalYearlyAverage: (account) =>
account.allTimeSummary?.spentTotalYearlyAverage && amountAsString(account.allTimeSummary.spentTotalYearlyAverage),
receivedTotalYearlyAverage: (account) =>
account.allTimeSummary?.receivedTotalYearlyAverage &&
amountAsString(account.allTimeSummary.receivedTotalYearlyAverage),
};

const hostedCollectives: RequestHandler<{ slug: string; format: 'csv' | 'json' }> = async (req, res) => {
Expand All @@ -340,13 +373,18 @@ const hostedCollectives: RequestHandler<{ slug: string; format: 'csv' | 'json' }
const hostSlug = req.params.slug;
assert(hostSlug, 'Please provide a slug');

const hostResult = await graphqlRequest(hostQuery, { hostSlug }, { version: 'v2', headers });
const host = hostResult.host;
assert(host, 'Could not find Host');

const fields = (get(req.query, 'fields', '') as string)
.split(',')
.map(trim)
.filter((v) => !!v) as Fields[];

const variables = {
hostSlug,
hostCurrency: host.currency,
limit: req.method === 'HEAD' ? 0 : req.query.limit ? toNumber(req.query.limit) : 1000,
offset: req.query.offset ? toNumber(req.query.offset) : 0,
sort: req.query.sort && JSON.parse(req.query.sort as string),
Expand All @@ -367,6 +405,7 @@ const hostedCollectives: RequestHandler<{ slug: string; format: 'csv' | 'json' }
'numberOfPayeesYear',
'numberOfContributionsYear',
'valueOfContributionsYear',
'valueOfRefundedContributionsYear',
'valueOfHostFeeYear',
'spentTotalYear',
'receivedTotalYear',
Expand All @@ -380,13 +419,16 @@ const hostedCollectives: RequestHandler<{ slug: string; format: 'csv' | 'json' }
'numberOfPayeesAllTime',
'numberOfContributionsAllTime',
'valueOfContributionsAllTime',
'valueOfRefundedContributionsAllTime',
'valueOfHostFeeAllTime',
'spentTotalAllTime',
'receivedTotalAllTime',
'expenseMonthlyAverageCount',
'expenseMonthlyAverageTotal',
'contributionMonthlyAverageCount',
'contributionMonthlyAverageTotal',
'spentTotalYearlyAverage',
'receivedTotalYearlyAverage',
].includes(field),
),
};
Expand Down