mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-23 17:19:37 +02:00
* Extract currency conversion and rate limiting functions to helpers * Add script to create prices from CSV for Stripe integration * Add tests for create prices from CSV script * Add usage documentation for create_prices_from_csv script * Add `planCode` metadata * Temp: Plans CSV example * Revert "Temp: Plans CSV example" This reverts commit 810b1ed67052f7a1a0deb20b70f14507a282fcf1. * Various improvements to price and product creation script --------- Co-authored-by: Tim Down <158919+timdown@users.noreply.github.com> GitOrigin-RevId: c015c6dd904db3143781581db4210cef282a4070
131 lines
3.5 KiB
JavaScript
131 lines
3.5 KiB
JavaScript
/* eslint-disable @overleaf/require-script-runner */
|
|
// This file contains helper functions used by other scripts.
|
|
// The scripts that import these helpers should use Script Runner.
|
|
|
|
/**
|
|
* @import Stripe from 'stripe'
|
|
* @import { getRegionClient } from '../../modules/subscriptions/app/src/StripeClient.mjs'
|
|
*/
|
|
|
|
/**
|
|
* @export
|
|
* @typedef {Object} CSVSubscriptionChange
|
|
* @property {string} subscription_id
|
|
* @property {string} current_lookup_key
|
|
* @property {string} new_lookup_key
|
|
* @property {string} current_add_on_lookup_key
|
|
* @property {string} new_add_on_lookup_key
|
|
*/
|
|
|
|
/**
|
|
* @export
|
|
* @typedef {'renewal' | 'now'} Timeframe
|
|
*/
|
|
|
|
/**
|
|
* @export
|
|
* @typedef {ReturnType<typeof getRegionClient>} StripeClient
|
|
*/
|
|
|
|
/**
|
|
* Custom error class for reportable errors that should be written to CSV output
|
|
*/
|
|
export class ReportError extends Error {
|
|
/**
|
|
* @param {string} status - The error status code for CSV output
|
|
* @param {string} message - The error message
|
|
*/
|
|
constructor(status, message) {
|
|
super(message)
|
|
this.status = status
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the product ID from a Stripe Subscription Item
|
|
*
|
|
* @param {Stripe.SubscriptionItem | Stripe.SubscriptionSchedule.Phase.Item} item
|
|
* @returns {string}
|
|
*/
|
|
export function getProductIdFromItem(item) {
|
|
const product =
|
|
typeof item.price === 'string'
|
|
? null
|
|
: 'product' in item.price
|
|
? item.price.product
|
|
: null
|
|
return typeof product === 'string' ? product : (product?.id ?? '')
|
|
}
|
|
|
|
/**
|
|
* Gets the price ID from a Stripe Subscription Item
|
|
*
|
|
* @param {Stripe.SubscriptionItem | Stripe.SubscriptionSchedule.Phase.Item} item
|
|
* @returns {string}
|
|
*/
|
|
export function getPriceIdFromItem(item) {
|
|
return typeof item.price === 'string' ? item.price : (item.price?.id ?? '')
|
|
}
|
|
|
|
/**
|
|
* Gets the product ID from a Stripe Price object
|
|
*
|
|
* @param {Stripe.Price} price
|
|
* @returns {string}
|
|
*/
|
|
export function getProductIdFromPrice(price) {
|
|
return typeof price.product === 'string'
|
|
? price.product
|
|
: (price.product?.id ?? '')
|
|
}
|
|
|
|
/**
|
|
* Sleep function to respect Stripe rate limits (100 requests per second)
|
|
*/
|
|
export async function rateLimitSleep() {
|
|
return new Promise(resolve => setTimeout(resolve, 50))
|
|
}
|
|
|
|
/**
|
|
* Convert amount to minor units (cents for most currencies)
|
|
* Some currencies like JPY, KRW, CLP, VND don't have cents
|
|
*
|
|
* Copied from services/web/frontend/js/shared/utils/currency.ts
|
|
*
|
|
* @param {number} amount - Amount in major units (dollars, euros, etc.)
|
|
* @param {string} currency - Currency code (lowercase)
|
|
* @returns {number} Amount in minor units
|
|
*/
|
|
export function convertToMinorUnits(amount, currency) {
|
|
const isNoCentsCurrency = ['clp', 'jpy', 'krw', 'vnd'].includes(
|
|
currency.toLowerCase()
|
|
)
|
|
|
|
// Determine the multiplier based on currency
|
|
let multiplier = 100 // default for most currencies (2 decimal places)
|
|
|
|
if (isNoCentsCurrency) {
|
|
multiplier = 1 // no decimal places
|
|
}
|
|
|
|
// Convert and round to an integer
|
|
return Math.round(amount * multiplier)
|
|
}
|
|
|
|
/**
|
|
* Convert amount from minor units (cents for most currencies)
|
|
* Some currencies like JPY, KRW, CLP, VND don't have cents
|
|
*
|
|
* Copied from services/web/modules/subscriptions/app/src/StripeClient.mjs
|
|
*
|
|
* @param {number} amount - price in the smallest currency unit (e.g. dollar cents, CLP units, ...)
|
|
* @param {StripeCurrencyCode} currency - currency code
|
|
* @return {number}
|
|
*/
|
|
export function convertFromMinorUnits(amount, currency) {
|
|
const isNoCentsCurrency = ['clp', 'jpy', 'krw', 'vnd'].includes(
|
|
currency.toLowerCase()
|
|
)
|
|
return isNoCentsCurrency ? amount : amount / 100
|
|
}
|