{"size": 5296, "ext": "js", "max_stars_repo_path": "server/graphql/v2/object/AccountStats.js", "max_stars_repo_name": "negotiamini/opencollective-api", "max_stars_repo_stars_event_min_datetime": "2017-06-01T02:21:32.000Z", "max_stars_repo_stars_event_max_datetime": "2022-03-30T12:05:52.000Z", "max_issues_repo_path": "server/graphql/v2/object/AccountStats.js", "max_issues_repo_name": "negotiamini/opencollective-api", "max_issues_repo_issues_event_min_datetime": "2017-05-16T20:17:05.000Z", "max_issues_repo_issues_event_max_datetime": "2022-03-31T12:02:59.000Z", "max_forks_repo_path": "server/graphql/v2/object/AccountStats.js", "max_forks_repo_name": "negotiamini/opencollective-api", "max_forks_repo_forks_event_min_datetime": "2017-05-14T20:12:33.000Z", "max_forks_repo_forks_event_max_datetime": "2022-03-22T07:11:01.000Z"}
{"max_stars_count": 297, "max_issues_count": 1863, "max_forks_count": 205, "avg_line_length": 34.1677419355, "max_line_length": 129, "alphanum_fraction": 0.5634441088}
import { GraphQLList, GraphQLNonNull, GraphQLObjectType, GraphQLString } from 'graphql';
import { GraphQLDateTime } from 'graphql-iso-date';
import { get, has } from 'lodash';

import queries from '../../../lib/queries';
import { Currency } from '../enum/Currency';
import { ExpenseType } from '../enum/ExpenseType';
import { TransactionKind } from '../enum/TransactionKind';
import { idEncode } from '../identifiers';
import { Amount } from '../object/Amount';

export const AccountStats = new GraphQLObjectType({
  name: 'AccountStats',
  description: 'Stats for the Account',
  fields: () => {
    return {
      id: {
        type: GraphQLString,
        resolve(collective) {
          return idEncode(collective.id);
        },
      },
      balanceWithBlockedFunds: {
        description: 'Amount of money in cents in the currency of the collective currently available to spend',
        type: new GraphQLNonNull(Amount),
        resolve(account, args, req) {
          return account.getBalanceWithBlockedFundsAmount({ loaders: req.loaders });
        },
      },
      balance: {
        description: 'Amount of money in cents in the currency of the collective',
        type: new GraphQLNonNull(Amount),
        args: {
          dateFrom: {
            type: GraphQLDateTime,
            description: 'Calculate balance beginning from this date.',
          },
          dateTo: {
            type: GraphQLDateTime,
            description: 'Calculate balance until this date.',
          },
        },
        resolve(account, args, req) {
          return account.getBalanceAmount({ loaders: req.loaders, startDate: args.dateFrom, endDate: args.dateTo });
        },
      },
      monthlySpending: {
        description: 'Average amount spent per month based on the last 90 days',
        type: new GraphQLNonNull(Amount),
        async resolve(collective) {
          // if we fetched the collective with the raw query to sort them by their monthly spending we don't need to recompute it
          if (has(collective, 'dataValues.monthlySpending')) {
            return {
              value: get(collective, 'dataValues.monthlySpending'),
              currency: collective.currency,
            };
          } else {
            return {
              value: await collective.getMonthlySpending(),
              currency: collective.currency,
            };
          }
        },
      },
      totalAmountSpent: {
        description: 'Total amount spent',
        type: new GraphQLNonNull(Amount),
        async resolve(collective) {
          return {
            value: await collective.getTotalAmountSpent(),
            currency: collective.currency,
          };
        },
      },
      totalAmountReceived: {
        description: 'Net amount received',
        type: new GraphQLNonNull(Amount),
        args: {
          kind: {
            type: new GraphQLList(TransactionKind),
            description: 'Filter by kind',
          },
          dateTo: {
            type: GraphQLDateTime,
            description: 'Calculate total amount received before this date',
          },
          dateFrom: {
            type: GraphQLDateTime,
            description: 'Calculate total amount received after this date',
          },
        },
        resolve(collective, args) {
          const kind = args.kind && args.kind.length > 0 ? args.kind : undefined;
          return collective.getTotalAmountReceivedAmount({ kind, startDate: args.dateFrom, endDate: args.dateTo });
        },
      },
      totalPaidExpenses: {
        description: 'Total of paid expenses, filter per expensetype',
        type: new GraphQLNonNull(Amount),
        args: {
          expenseType: {
            type: new GraphQLList(ExpenseType),
            description: 'Filter by ExpenseType',
          },
          dateTo: {
            type: GraphQLDateTime,
            description: 'Calculate total amount received before this date',
          },
          dateFrom: {
            type: GraphQLDateTime,
            description: 'Calculate total amount received after this date',
          },
          currency: {
            type: Currency,
            description: 'An optional currency. If not provided, will use the collective currency.',
          },
        },
        async resolve(collective, args) {
          return collective.getTotalPaidExpensesAmount({
            startDate: args.dateFrom,
            endDate: args.dateTo,
            expenseType: args.expenseType,
            currency: args.currency,
          });
        },
      },
      yearlyBudget: {
        type: new GraphQLNonNull(Amount),
        async resolve(collective) {
          return {
            value: await collective.getYearlyIncome(),
            currency: collective.currency,
          };
        },
      },
      yearlyBudgetManaged: {
        type: new GraphQLNonNull(Amount),
        async resolve(collective) {
          if (collective.isHostAccount) {
            return {
              value: await queries.getTotalAnnualBudgetForHost(collective.id),
              currency: collective.currency,
            };
          } else {
            return {
              value: 0,
              currency: collective.currency,
            };
          }
        },
      },
    };
  },
});
