Skip to content

Commit

Permalink
feat: add new monthly average fields (#581)
Browse files Browse the repository at this point in the history
  • Loading branch information
kewitz authored Nov 8, 2024
1 parent 266e14a commit e51c8f9
Show file tree
Hide file tree
Showing 2 changed files with 175 additions and 15 deletions.
133 changes: 131 additions & 2 deletions src/graphql/schemaV2.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -5159,6 +5159,31 @@ type AccountStats {
@deprecated(reason: "2022-12-14: this is not used anymore as results should be fast by default")
): Amount!

"""
Amount pledged time series
"""
amountPledgedTimeSeries(
"""
The start date of the time series
"""
dateFrom: DateTime

"""
The end date of the time series
"""
dateTo: DateTime

"""
The time unit of the time series (such as MONTH, YEAR, WEEK etc). If no value is provided this is calculated using the dateFrom and dateTo values.
"""
timeUnit: TimeUnit

"""
Include expected funds.
"""
includeExpectedFunds: Boolean = false
): TimeSeriesAmount!

"""
Total amount received time series
"""
Expand Down Expand Up @@ -5469,6 +5494,11 @@ type AccountStats {
Include transactions from children (Projects and Events)
"""
includeChildren: Boolean = false

"""
Filter by kind
"""
kind: [TransactionKind]
): [AmountStats]

"""
Expand All @@ -5494,6 +5524,11 @@ type AccountStats {
Include transactions from children (Projects and Events)
"""
includeChildren: Boolean = false

"""
Filter by kind
"""
kind: [TransactionKind]
): TimeSeriesAmount!
}

Expand Down Expand Up @@ -5553,6 +5588,7 @@ enum TimeUnit {
type TimeSeriesAmountNode {
date: DateTime!
amount: Amount!
count: Int
label: String
}

Expand Down Expand Up @@ -6910,6 +6946,16 @@ type TransactionsImport {
"""
lastSyncAt: DateTime

"""
Whether the import is currently syncing
"""
isSyncing: Boolean!

"""
Cursor that defines where the last sync left off. Useful to know if there is new data to sync
"""
lastSyncCursor: String

"""
Connected account linked to the import
"""
Expand All @@ -6918,7 +6964,27 @@ type TransactionsImport {
"""
List of rows in the import
"""
rows: TransactionsImportRowCollection!
rows(
"""
The number of results to fetch (default 10, max 1000)
"""
limit: Int! = 100

"""
The offset to use to fetch
"""
offset: Int! = 0

"""
Filter rows by status
"""
status: TransactionsImportRowStatus

"""
Search by text
"""
searchTerm: String
): TransactionsImportRowCollection!
stats: TransactionsImportStats
}

Expand Down Expand Up @@ -7001,6 +7067,26 @@ The `JSONObject` scalar type represents JSON objects as specified by [ECMA-404](
"""
scalar JSONObject

"""
The status of a row in a transactions import
"""
enum TransactionsImportRowStatus {
"""
The row has not been processed yet
"""
PENDING

"""
The row has been linked to an existing expense or order
"""
LINKED

"""
The row has been ignored
"""
IGNORED
}

type TransactionsImportStats {
"""
Total number of rows in the import
Expand Down Expand Up @@ -9514,13 +9600,36 @@ Return a summary of transaction info about a given account within the context of
"""
type HostedAccountSummary {
expenseCount: Int

"""
Average calculated based on the number of months since the first transaction of this kind within the requested time frame
"""
expenseMonthlyAverageCount: Float
expenseTotal: Amount

"""
Average calculated based on the number of months since the first transaction of this kind within the requested time frame
"""
expenseMonthlyAverageTotal: Amount
expenseMaxValue: Amount
expenseDistinctPayee: Int
contributionCount: Int

"""
Average calculated based on the number of months since the first transaction of this kind within the requested time frame
"""
contributionMonthlyAverageCount: Float
contributionTotal: Amount

"""
Average calculated based on the number of months since the first transaction of this kind within the requested time frame
"""
contributionMonthlyAverageTotal: Amount
hostFeeTotal: Amount
spentTotal: Amount
receivedTotal: Amount
spentTotalMonthlyAverage: Amount
receivedTotalMonthlyAverage: Amount
}

"""
Expand Down Expand Up @@ -19990,6 +20099,16 @@ type Mutation {
name: String
): PlaidConnectAccountResponse!

"""
Manually request a sync for Plaid account
"""
syncPlaidAccount(
"""
The connected account to refresh
"""
connectedAccount: ConnectedAccountReferenceInput!
): TransactionsImport!

"""
[Root only] Edits account flags (deleted, banned, archived, trusted host)
"""
Expand Down Expand Up @@ -20202,7 +20321,17 @@ type Mutation {
"""
Rows to update
"""
rows: [TransactionsImportRowUpdateInput!]!
rows: [TransactionsImportRowUpdateInput!]

"""
Whether to ignore all non-processed rows
"""
dismissAll: Boolean

"""
Whether to restore all dismissed rows
"""
restoreAll: Boolean
): TransactionsImport!

"""
Expand Down
57 changes: 44 additions & 13 deletions src/server/controllers/hosted-collectives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,22 @@ type Fields =
| 'valueOfContributionsYear'
| 'valueOfHostFeeYear'
| 'spentTotalYear'
| 'receivedTotalYear'
| 'numberOfExpensesAllTime'
| 'valueOfExpensesAllTime'
| 'maxExpenseValueAllTime'
| 'numberOfPayeesAllTime'
| 'numberOfContributionsAllTime'
| 'valueOfContributionsAllTime'
| 'valueOfHostFeeAllTime'
| 'spentTotalAllTime';
| 'spentTotalAllTime'
| 'receivedTotalAllTime'
| 'expenseMonthlyAverageCount'
| 'expenseMonthlyAverageTotal'
| 'contributionMonthlyAverageCount'
| 'contributionMonthlyAverageTotal'
| 'spentTotalMonthlyAverage'
| 'receivedTotalMonthlyAverage';

export const hostedCollectivesQuery = gqlV2`
query HostedCollectives(
Expand Down Expand Up @@ -118,15 +126,6 @@ export const hostedCollectivesQuery = gqlV2`
value
currency
}
totalAmountSpent {
value
currency
}
totalAmountReceived(net: true) {
value
currency
}
}
policies {
id
Expand Down Expand Up @@ -167,7 +166,8 @@ export const hostedCollectivesQuery = gqlV2`
contributionCount
contributionTotal { valueInCents, value, currency }
hostFeeTotal { valueInCents, value, currency }
spentTotal { valueInCents, value, currency}
spentTotal { valueInCents, value, currency }
receivedTotal { valueInCents, value, currency }
}
allTimeSummary: summary @include(if: $includeAllTimeSummary) {
expenseTotal { valueInCents, value, currency }
Expand All @@ -177,7 +177,14 @@ export const hostedCollectivesQuery = gqlV2`
contributionCount
contributionTotal { valueInCents, value, currency }
hostFeeTotal { valueInCents, value, currency }
spentTotal { 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 }
}
}
admins: members(role: [ADMIN]) {
Expand Down Expand Up @@ -277,6 +284,8 @@ const csvMapping: Record<Fields, string | Function> = {
valueOfHostFeeYear: (account) =>
account.yearSummary?.hostFeeTotal && amountAsString(account.yearSummary.hostFeeTotal),
spentTotalYear: (account) => account.yearSummary?.spentTotal && amountAsString(account.yearSummary.spentTotal),
receivedTotalYear: (account) =>
account.yearSummary?.receivedTotal && amountAsString(account.yearSummary.receivedTotal),
numberOfExpensesAllTime: (account) => account.allTimeSummary?.expenseCount,
valueOfExpensesAllTime: (account) =>
account.allTimeSummary?.expenseTotal && amountAsString(account.allTimeSummary.expenseTotal),
Expand All @@ -290,14 +299,28 @@ const csvMapping: Record<Fields, string | Function> = {
account.allTimeSummary?.hostFeeTotal && amountAsString(account.allTimeSummary.hostFeeTotal),
spentTotalAllTime: (account) =>
account.allTimeSummary?.spentTotal && amountAsString(account.allTimeSummary.spentTotal),
receivedTotalAllTime: (account) =>
account.allTimeSummary?.receivedTotal && amountAsString(account.allTimeSummary.receivedTotal),
expenseMonthlyAverageCount: (account) => account.allTimeSummary?.expenseMonthlyAverageCount,
expenseMonthlyAverageTotal: (account) =>
account.allTimeSummary?.expenseMonthlyAverageTotal &&
amountAsString(account.allTimeSummary.expenseMonthlyAverageTotal),
contributionMonthlyAverageCount: (account) => account.allTimeSummary?.contributionMonthlyAverageCount,
contributionMonthlyAverageTotal: (account) =>
account.allTimeSummary?.contributionMonthlyAverageTotal &&
amountAsString(account.allTimeSummary.contributionMonthlyAverageTotal),
spentTotalMonthlyAverage: (account) =>
account.allTimeSummary?.spentTotalMonthlyAverage && amountAsString(account.allTimeSummary.spentTotalMonthlyAverage),
receivedTotalMonthlyAverage: (account) =>
account.allTimeSummary?.receivedTotalMonthlyAverage &&
amountAsString(account.allTimeSummary.receivedTotalMonthlyAverage),
};

const hostedCollectives: RequestHandler<{ slug: string; format: 'csv' | 'json' }> = async (req, res) => {
if (!['HEAD', 'GET'].includes(req.method)) {
res.status(405).send({ error: { message: 'Method not allowed' } });
return;
}

try {
// Forward Api Key or Authorization header
const headers = {};
Expand Down Expand Up @@ -345,6 +368,8 @@ const hostedCollectives: RequestHandler<{ slug: string; format: 'csv' | 'json' }
'numberOfContributionsYear',
'valueOfContributionsYear',
'valueOfHostFeeYear',
'spentTotalYear',
'receivedTotalYear',
].includes(field),
),
includeAllTimeSummary: fields.some((field) =>
Expand All @@ -356,6 +381,12 @@ const hostedCollectives: RequestHandler<{ slug: string; format: 'csv' | 'json' }
'numberOfContributionsAllTime',
'valueOfContributionsAllTime',
'valueOfHostFeeAllTime',
'spentTotalAllTime',
'receivedTotalAllTime',
'expenseMonthlyAverageCount',
'expenseMonthlyAverageTotal',
'contributionMonthlyAverageCount',
'contributionMonthlyAverageTotal',
].includes(field),
),
};
Expand Down

0 comments on commit e51c8f9

Please sign in to comment.