diff --git a/src/graphql/schemaV2.graphql b/src/graphql/schemaV2.graphql index 0e4e678e..8871ac28 100644 --- a/src/graphql/schemaV2.graphql +++ b/src/graphql/schemaV2.graphql @@ -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 """ @@ -5469,6 +5494,11 @@ type AccountStats { Include transactions from children (Projects and Events) """ includeChildren: Boolean = false + + """ + Filter by kind + """ + kind: [TransactionKind] ): [AmountStats] """ @@ -5494,6 +5524,11 @@ type AccountStats { Include transactions from children (Projects and Events) """ includeChildren: Boolean = false + + """ + Filter by kind + """ + kind: [TransactionKind] ): TimeSeriesAmount! } @@ -5553,6 +5588,7 @@ enum TimeUnit { type TimeSeriesAmountNode { date: DateTime! amount: Amount! + count: Int label: String } @@ -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 """ @@ -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 } @@ -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 @@ -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 } """ @@ -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) """ @@ -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! """ diff --git a/src/server/controllers/hosted-collectives.ts b/src/server/controllers/hosted-collectives.ts index 111a6406..a5b39d22 100644 --- a/src/server/controllers/hosted-collectives.ts +++ b/src/server/controllers/hosted-collectives.ts @@ -45,6 +45,7 @@ type Fields = | 'valueOfContributionsYear' | 'valueOfHostFeeYear' | 'spentTotalYear' + | 'receivedTotalYear' | 'numberOfExpensesAllTime' | 'valueOfExpensesAllTime' | 'maxExpenseValueAllTime' @@ -52,7 +53,14 @@ type Fields = | 'numberOfContributionsAllTime' | 'valueOfContributionsAllTime' | 'valueOfHostFeeAllTime' - | 'spentTotalAllTime'; + | 'spentTotalAllTime' + | 'receivedTotalAllTime' + | 'expenseMonthlyAverageCount' + | 'expenseMonthlyAverageTotal' + | 'contributionMonthlyAverageCount' + | 'contributionMonthlyAverageTotal' + | 'spentTotalMonthlyAverage' + | 'receivedTotalMonthlyAverage'; export const hostedCollectivesQuery = gqlV2` query HostedCollectives( @@ -118,15 +126,6 @@ export const hostedCollectivesQuery = gqlV2` value currency } - totalAmountSpent { - value - currency - } - totalAmountReceived(net: true) { - value - currency - } - } policies { id @@ -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 } @@ -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]) { @@ -277,6 +284,8 @@ const csvMapping: Record = { 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), @@ -290,6 +299,21 @@ const csvMapping: Record = { 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) => { @@ -297,7 +321,6 @@ const hostedCollectives: RequestHandler<{ slug: string; format: 'csv' | 'json' } res.status(405).send({ error: { message: 'Method not allowed' } }); return; } - try { // Forward Api Key or Authorization header const headers = {}; @@ -345,6 +368,8 @@ const hostedCollectives: RequestHandler<{ slug: string; format: 'csv' | 'json' } 'numberOfContributionsYear', 'valueOfContributionsYear', 'valueOfHostFeeYear', + 'spentTotalYear', + 'receivedTotalYear', ].includes(field), ), includeAllTimeSummary: fields.some((field) => @@ -356,6 +381,12 @@ const hostedCollectives: RequestHandler<{ slug: string; format: 'csv' | 'json' } 'numberOfContributionsAllTime', 'valueOfContributionsAllTime', 'valueOfHostFeeAllTime', + 'spentTotalAllTime', + 'receivedTotalAllTime', + 'expenseMonthlyAverageCount', + 'expenseMonthlyAverageTotal', + 'contributionMonthlyAverageCount', + 'contributionMonthlyAverageTotal', ].includes(field), ), };