Merge pull request #1058 from automatisch/remove-payment-plans

chore: remove payment plan model and related functionality
This commit is contained in:
Ali BARIN
2023-04-16 20:32:01 +02:00
committed by GitHub
9 changed files with 25 additions and 242 deletions

View File

@@ -0,0 +1,25 @@
import { Knex } from 'knex';
import appConfig from '../../config/app';
export async function up(knex: Knex): Promise<void> {
if (!appConfig.isCloud) return;
return knex.schema.dropTable('payment_plans');
}
export async function down(knex: Knex): Promise<void> {
if (!appConfig.isCloud) return;
return knex.schema.createTable('payment_plans', (table) => {
table.uuid('id').primary().defaultTo(knex.raw('gen_random_uuid()'));
table.string('name').notNullable();
table.integer('task_count').notNullable();
table.uuid('user_id').references('id').inTable('users');
table.string('stripe_customer_id');
table.string('stripe_subscription_id');
table.timestamp('current_period_started_at').nullable();
table.timestamp('current_period_ends_at').nullable();
table.timestamp('deleted_at').nullable();
table.timestamps(true, true);
});
}

View File

@@ -1,33 +0,0 @@
import appConfig from '../../config/app';
import Context from '../../types/express/context';
// TODO: remove as getBillingAndUsageData query has been introduced
const getUsageData = async (
_parent: unknown,
_params: unknown,
context: Context
) => {
if (!appConfig.isCloud) return;
const usageData = await context.currentUser
.$relatedQuery('currentUsageData')
.throwIfNotFound();
const subscription = await usageData
.$relatedQuery('subscription')
.throwIfNotFound();
const plan = subscription.plan;
const computedUsageData = {
name: plan.name,
allowedTaskCount: plan.quota,
consumedTaskCount: usageData.consumedTaskCount,
remainingTaskCount: plan.quota - usageData.consumedTaskCount,
nextResetAt: usageData.nextResetAt,
};
return computedUsageData;
};
export default getUsageData;

View File

@@ -11,7 +11,6 @@ import getExecutionSteps from './queries/get-execution-steps';
import getDynamicData from './queries/get-dynamic-data';
import getDynamicFields from './queries/get-dynamic-fields';
import getCurrentUser from './queries/get-current-user';
import getUsageData from './queries/get-usage-data.ee';
import getPaymentPlans from './queries/get-payment-plans.ee';
import getPaddleInfo from './queries/get-paddle-info.ee';
import getBillingAndUsage from './queries/get-billing-and-usage.ee';
@@ -35,7 +34,6 @@ const queryResolvers = {
getDynamicData,
getDynamicFields,
getCurrentUser,
getUsageData,
getPaymentPlans,
getPaddleInfo,
getBillingAndUsage,

View File

@@ -34,7 +34,6 @@ type Query {
parameters: JSONObject
): [SubstepArgument]
getCurrentUser: User
getUsageData: GetUsageData
getPaymentPlans: [PaymentPlan]
getPaddleInfo: GetPaddleInfo
getBillingAndUsage: GetBillingAndUsage
@@ -529,14 +528,6 @@ type Usage {
task: Int
}
type GetUsageData {
name: String
allowedTaskCount: Int
consumedTaskCount: Int
remainingTaskCount: Int
nextResetAt: String
}
type GetPaddleInfo {
sandbox: Boolean
vendorId: Int

View File

@@ -1,53 +0,0 @@
import Base from './base';
import User from './user';
class PaymentPlan extends Base {
id!: string;
name!: string;
taskCount: number;
userId!: string;
stripeCustomerId!: string;
stripeSubscriptionId!: string;
currentPeriodStartedAt!: string;
currentPeriodEndsAt!: string;
user?: User;
static tableName = 'payment_plans';
static jsonSchema = {
type: 'object',
required: [
'name',
'taskCount',
'userId',
'stripeCustomerId',
'stripeSubscriptionId',
'currentPeriodStartedAt',
'currentPeriodEndsAt',
],
properties: {
id: { type: 'string', format: 'uuid' },
name: { type: 'string' },
taskCount: { type: 'integer' },
userId: { type: 'string', format: 'uuid' },
stripeCustomerId: { type: 'string' },
stripeSubscriptionId: { type: 'string' },
currentPeriodStartedAt: { type: 'string' },
currentPeriodEndsAt: { type: 'string' },
},
};
static relationMappings = () => ({
user: {
relation: Base.BelongsToOneRelation,
modelClass: User,
join: {
from: 'payment_plans.user_id',
to: 'users.id',
},
},
});
}
export default PaymentPlan;

View File

@@ -1,54 +0,0 @@
import * as React from 'react';
import { Link } from 'react-router-dom';
import Alert from '@mui/material/Alert';
import Snackbar from '@mui/material/Snackbar';
import Typography from '@mui/material/Typography';
import Stack from '@mui/material/Stack';
import Button from '@mui/material/Button';
import LinearProgress from '@mui/material/LinearProgress';
import useFormatMessage from 'hooks/useFormatMessage';
import useUsageAlert from 'hooks/useUsageAlert.ee';
export default function UsageAlert() {
const formatMessage = useFormatMessage();
const usageAlert = useUsageAlert();
if (!usageAlert.showAlert) return (<React.Fragment />);
return (
<Snackbar
anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}
open
>
<Alert
icon={false}
sx={{ fontWeight: 500, minWidth: 410 }}
severity={usageAlert.hasExceededLimit ? 'error' : 'warning'}
>
<Stack direction="row" gap={4} mb={1}>
<Typography
variant="subtitle2"
sx={{ display: 'flex', alignItems: 'center' }}
>
{usageAlert.alertMessage}
</Typography>
<Button
component={Link}
size="small"
to={usageAlert.url}
sx={{ minWidth: 100 }}
>
{formatMessage('usageAlert.viewPlans')}
</Button>
</Stack>
<LinearProgress
variant="determinate"
value={usageAlert.consumptionPercentage}
/>
</Alert>
</Snackbar>
);
}

View File

@@ -1,14 +0,0 @@
import { gql } from '@apollo/client';
export const GET_USAGE_DATA = gql`
query GetUsageData {
getUsageData {
name
allowedTaskCount
consumedTaskCount
remainingTaskCount
nextResetAt
}
}
`;

View File

@@ -1,47 +0,0 @@
import * as URLS from 'config/urls';
import useFormatMessage from './useFormatMessage';
import useUsageData from './useUsageData.ee';
type UseUsageAlertReturn = {
showAlert: true;
hasExceededLimit: boolean;
alertMessage: string;
url: string;
consumptionPercentage: number;
};
type UseUsageNoAlertReturn = {
showAlert: false;
};
export default function useUsageAlert(): UseUsageAlertReturn | UseUsageNoAlertReturn {
const {
allowedTaskCount,
consumedTaskCount,
nextResetAt,
loading
} = useUsageData();
const formatMessage = useFormatMessage();
if (loading) {
return { showAlert: false };
}
const withinUsageThreshold = consumedTaskCount > allowedTaskCount * 0.7;
const consumptionPercentage = consumedTaskCount / allowedTaskCount * 100;
const hasExceededLimit = consumedTaskCount >= allowedTaskCount;
const alertMessage = formatMessage('usageAlert.informationText', {
allowedTaskCount,
consumedTaskCount,
relativeResetDate: nextResetAt?.toRelative(),
});
return {
showAlert: withinUsageThreshold,
hasExceededLimit,
alertMessage,
consumptionPercentage,
url: URLS.SETTINGS_PLAN_UPGRADE,
};
}

View File

@@ -1,30 +0,0 @@
import { useQuery } from '@apollo/client';
import { DateTime } from 'luxon';
import { GET_USAGE_DATA } from 'graphql/queries/get-usage-data.ee';
type UseUsageDataReturn = {
name: string;
allowedTaskCount: number;
consumedTaskCount: number;
remainingTaskCount: number;
nextResetAt: DateTime;
loading: boolean;
};
export default function useUsageData(): UseUsageDataReturn {
const { data, loading } = useQuery(GET_USAGE_DATA);
const usageData = data?.getUsageData;
const nextResetAt = usageData?.nextResetAt;
const nextResetAtDateTimeObject = nextResetAt && DateTime.fromMillis(Number(nextResetAt));
return {
name: usageData?.name,
allowedTaskCount: usageData?.allowedTaskCount,
consumedTaskCount: usageData?.consumedTaskCount,
remainingTaskCount: usageData?.remainingTaskCount,
nextResetAt: nextResetAtDateTimeObject,
loading
};
}