<commit_before>import React, { Component } from 'react';
import { connect } from 'react-apollo';
import gql from 'graphql-tag';
import moment from 'moment';
import BalancePanel from 'components/billing/balance-panel';
import PaymentInfoPanel from 'components/billing/payment-info-panel';
import UsagePanel from 'components/billing/usage-panel';
import AddCardForm from 'containers/billing/add-card-form';
import TransactionsList from 'components/billing/transactions-list';
import 'containers/billing/billing.scss';
import { setBalance, setUsage } from 'redux/modules/transaction-group';

const transactionRangeQuery =
  gql`query usageTransactions($startDate: String!, $endDate: String!) {
      credits(startDate: $startDate, endDate: $endDate) {
        id,
        paid_amount,
        created,
        type
      }
      debits(startDate: $startDate, endDate: $endDate) {
        id,
        amount,
        created,
        type
      },
    }`;

const mapQueriesToProps = () => {
  return {
    paymentProcessor: {
      query: gql`query {
        paymentProcessor {
          id,
          name,
          billingDate,
          defaultPaymentMethod {
            merchant,
            lastFour,
            id
          },
          error
        }
      }`
    },
    transactions: {
      query: gql`query {
        credits {
          id,
          paid_amount,
          created,
          type
        },
        debits {
          id,
          amount,
          created,
          type
        }
      }`
    }
  }
};

const mapMutationsToProps = () => {
  return {
    removeCard: (paymentProcessorId, paymentMethodId) => {
      return {
        // TODO: maybe add `id,` to get query update?
        mutation: gql`
        mutation removePaymentMethod($paymentProcessorId: String!, $paymentMethodId: String!) {
          removePaymentMethod(paymentProcessorId: $paymentProcessorId, paymentMethodId: $paymentMethodId) {
            id,
            name,
            billingDate,
            defaultPaymentMethod {
              merchant,
              lastFour,
              id
            },
            error
          }
        }`,
        variables: {
          paymentProcessorId,
          paymentMethodId
        }
      };
    }
  };
};

const mapDispatchToProps = {
  setBalance,
  setUsage
};

const mapStateToProps = ({transactionGroup: {balance, usage}}) => {
  return {balance, usage};
};

let globalCounter = 0;

@connect({
  mapQueriesToProps,
  mapMutationsToProps,
  mapDispatchToProps,
  mapStateToProps
})

export default class Billing extends Component {
  componentWillReceiveProps(nextProps) {
    globalCounter++;
    if (globalCounter > 50) return;

    const {balance, usage} = nextProps;

    if (!!balance && !!usage) {
      return;
    }

    const {startDate: balanceStartDate, endDate: balanceEndDate} = this.getBalanceRange();
    const {startDate: usageStartDate, endDate: usageEndDate} = this.getUsageRange();

    if (!(balance && balance.loading)) {
      const balancePromise = this.props.query({
        query: transactionRangeQuery,
        variables: {
          startDate: balanceStartDate,
          endDate: balanceEndDate
        }
      });

      balancePromise.then(({data: {credits, debits}, loading}) => {
        const balance = this.calculateBalance(credits, debits);
        this.props.setBalance(balance);
      });
    }

    if (!(usage && usage.loading)) {
      const usagePromise = this.props.query({
        query: transactionRangeQuery,
        variables: {
          startDate: usageStartDate,
          endDate: usageEndDate
        }
      });

      usagePromise.then(({data: {credits, debits}}) => {
        const usage = this.calculateBalance(credits, debits);
        this.props.setUsage(usage);
      });
    }
  }

  getBalanceRange() {
    return this.getRange(1);
  }

  getUsageRange() {
    return this.getRange(0);
  }

  getRange(offset) {
    const {loading, paymentProcessor} = this.props.paymentProcessor;
    const billingDate = (loading || !paymentProcessor) ?
      (new Date).getDate() : paymentProcessor.billingDate;

    const format = 'YYYY-MM-DD HH:mm:ss.SSS';
    const today = new Date();
    const currentYearMonth = [
      today.getUTCFullYear(),
      // NB: add 1 to `.getUTCMonth` because `Date` uses 0 for Jan while `moment` uses 1
      today.getUTCMonth() + 1
    ];

    const dateThisMonthString = (date) => {
      return `${currentYearMonth.concat([date]).join('-')} 00:00:00.000`
    };

    const daysInMonth = moment.utc(
      dateThisMonthString(1), format
    )
      .subtract(offset, 'month')
      .add(1, 'month')
      .subtract(1, 'day')
      .date();

    const startDayOfMonth = (billingDate > daysInMonth) ? daysInMonth : billingDate;
    const startDate = moment.utc(<commit_msg>moar bugfixing<commit_after>import React, { Component } from 'react';
import { connect } from 'react-apollo';
import gql from 'graphql-tag';
import moment from 'moment';
import BalancePanel from 'components/billing/balance-panel';
import PaymentInfoPanel from 'components/billing/payment-info-panel';
import UsagePanel from 'components/billing/usage-panel';
import AddCardForm from 'containers/billing/add-card-form';
import TransactionsList from 'components/billing/transactions-list';
import 'containers/billing/billing.scss';
import { setBalance, setUsage } from 'redux/modules/transaction-group';

const transactionRangeQuery =
  gql`query usageTransactions($startDate: String!, $endDate: String!) {
      credits(startDate: $startDate, endDate: $endDate) {
        id,
        paid_amount,
        created,
        type
      }
      debits(startDate: $startDate, endDate: $endDate) {
        id,
        amount,
        created,
        type
      },
    }`;

const mapQueriesToProps = () => {
  return {
    paymentProcessor: {
      query: gql`query {
        paymentProcessor {
          id,
          name,
          billingDate,
          defaultPaymentMethod {
            merchant,
            lastFour,
            id
          },
          error
        }
      }`
    },
    transactions: {
      query: gql`query {
        credits {
          id,
          paid_amount,
          created,
          type
        },
        debits {
          id,
          amount,
          created,
          type
        }
      }`
    }
  }
};

const mapMutationsToProps = () => {
  return {
    removeCard: (paymentProcessorId, paymentMethodId) => {
      return {
        // TODO: maybe add `id,` to get query update?
        mutation: gql`
        mutation removePaymentMethod($paymentProcessorId: String!, $paymentMethodId: String!) {
          removePaymentMethod(paymentProcessorId: $paymentProcessorId, paymentMethodId: $paymentMethodId) {
            id,
            name,
            billingDate,
            defaultPaymentMethod {
              merchant,
              lastFour,
              id
            },
            error
          }
        }`,
        variables: {
          paymentProcessorId,
          paymentMethodId
        }
      };
    }
  };
};

const mapDispatchToProps = {
  setBalance,
  setUsage
};

const mapStateToProps = ({transactionGroup: {balance, usage}}) => {
  return {balance, usage};
};

let globalCounter = 0;

@connect({
  mapQueriesToProps,
  mapMutationsToProps,
  mapDispatchToProps,
  mapStateToProps
})

export default class Billing extends Component {
  componentWillReceiveProps(nextProps) {
    globalCounter++;
    if (globalCounter > 50) return;

    const {balance, usage} = nextProps;

    if (!!balance && !!usage) {
      return;
    }

    const {startDate: balanceStartDate, endDate: balanceEndDate} = this.getBalanceRange();
    const {startDate: usageStartDate, endDate: usageEndDate} = this.getUsageRange();

    if (!(balance && balance.loading)) {
      const balancePromise = this.props.query({
        query: transactionRangeQuery,
        variables: {
          startDate: balanceStartDate,
          endDate: balanceEndDate
        }
      });

      balancePromise.then(({data: {credits, debits}, loading}) => {
        const balance = this.calculateBalance(credits, debits);
        this.props.setBalance(balance);
      });
    }

    if (!(usage && usage.loading)) {
      const usagePromise = this.props.query({
        query: transactionRangeQuery,
        variables: {
          startDate: usageStartDate,
          endDate: usageEndDate
        }
      });

      usagePromise.then(({data: {credits, debits}}) => {
        const usage = this.calculateBalance(credits, debits);
        this.props.setUsage(usage);
      });
    }
  }

  getBalanceRange() {
    return this.getRange(1);
  }

  getUsageRange() {
    return this.getRange(0);
  }

  getRange(offset) {
    const {loading, paymentProcessor} = this.props.paymentProcessor;
    const billingDate = (loading || !paymentProcessor) ?
      (new Date).getDate() : paymentProcessor.billingDate;

    const format = 'YYYY-MM-DD HH:mm:ss.SSS';
    const today = new Date();
    const currentYearMonth = [
      today.getUTCFullYear(),
      today.getUTCMonth() + 1 - offset
    ];

    const dateThisMonthString = (date) => {
      return `${currentYearMonth.concat([date]).join('-')} 00:00:00.000`
    };

    const daysInMonth = moment.utc(
      dateThisMonthString(1), format
    )
      .subtract(offset, 'month')
      .add(1, 'month')
      .subtract(1, 'day')
      .date();

    const startDayOfMonth = (billingDate > daysInMonth) ? daysInMonth : billingDate;
    const startDate = moment.utc(
{'fraction_non_alphanumeric': 0.11464768087111298, 'fraction_numerical': 0.004083342058423201, 'mean_word_length': 2.284731774415406, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5694062', 'n_tokens_mistral': 2809, 'n_tokens_neox': 2765, 'n_words': 586}