#!/usr/bin/env ./node_modules/.bin/babel-node
import '../server/env';
import { get, last } from 'lodash';
import { listCharges } from '../server/paymentProviders/stripe/gateway';
import models from '../server/models';

/**
  Usage: ./scripts/diff-stripe-transactions.js [NB_CHARGES_TO_CHECK=100]
*/

const NB_CHARGES_TO_CHECK = parseInt(process.argv[2]) || 100;
const NB_CHARGES_PER_QUERY = 100; // Max allowed by Stripe
const NB_PAGES = NB_CHARGES_TO_CHECK / NB_CHARGES_PER_QUERY;

async function checkCharge(charge) {
  if (charge.failure_code) {
    // Ignore failed transaction
    console.log(`Ignoring ${charge.id} (failed transaction)`);
    return;
  }

  let transaction = await models.Transaction.findOne({
    where: { data: { charge: { id: charge.id } } },
    order: [['id', 'DESC']],
    // The JOIN is only here to optimize the query as searching in a JSON for thousands
    // of transaction can be pretty expensive.
    include: [
      {
        model: models.PaymentMethod,
        as: 'PaymentMethod',
        required: true,
        where: {
          customerId: charge.customer,
          service: 'stripe',
        },
      },
    ],
  });

  if (!transaction) {
    // This is an expensive query, we only run it if the above fails
    transaction = await models.Transaction.findOne({
      where: { data: { charge: { id: charge.id } } },
      order: [['id', 'DESC']],
    });

    if (!transaction) {
      console.error(`🚨️ Missing transaction for stripe charge ${charge.id}`);
    }
  }
}

async function main() {
  let lastChargeId;
  let totalAlreadyChecked = 0;

  console.info(`Starting the diff of Stripe VS Transactions for the latest ${NB_CHARGES_TO_CHECK} charges`);
  for (let pageNum = 0; pageNum < NB_PAGES; pageNum++) {
    // Log the current page
    const nbToCheckInThisPage = Math.min(NB_CHARGES_PER_QUERY, NB_CHARGES_TO_CHECK - totalAlreadyChecked);
    console.info(`🔎️ Checking transactions ${totalAlreadyChecked} to ${totalAlreadyChecked + nbToCheckInThisPage}`);

    // Retrieve the list and check all charges
    const charges = await listCharges({ limit: nbToCheckInThisPage, starting_after: lastChargeId });
    for (let idx = 0; idx < charges.data.length; idx++) {
      await checkCharge(charges.data[idx]);
      totalAlreadyChecked += 1;
      if (idx >= nbToCheckInThisPage) {
        break;
      }
    }

    // We reached the end
    if (!charges.has_more) {
      break;
    }

    // Register last charge for pagination
    lastChargeId = get(last(charges.data), 'id');
  }

  console.info('--------------------------------------\nDone!');
}

main().then(() => process.exit());

@@ -216,14 +216,56 @@
 ';%0A%0A
-/**%0A  
+if (process.argv.length %3C 3) %7B%0A  console.error('
 Usag
@@ -305,16 +305,34 @@
 ions.js 
+STRIPE_ACCOUNT_ID 
 %5BNB_CHAR
@@ -352,12 +352,73 @@
 100%5D
-%0A*/%0A
+');%0A  process.exit(1);%0A%7D%0A%0Aconst STRIPE_ACCOUNT = process.argv%5B2%5D;
 %0Acon
@@ -464,17 +464,17 @@
 ss.argv%5B
-2
+3
 %5D) %7C%7C 10
@@ -2212,16 +2212,32 @@
 Charges(
+STRIPE_ACCOUNT, 
 %7B limit:

Improve script to diff stripe transactions