Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Billable metrics rounding #1847

Merged
merged 9 commits into from
Nov 5, 2024
2 changes: 2 additions & 0 deletions src/components/form/ComboBox/ComboBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export const ComboBox = ({
error,
PopperProps,
className,
containerClassName = '',
searchQuery,
emptyText,
disableClearable = false,
Expand Down Expand Up @@ -91,6 +92,7 @@ export const ComboBox = ({

return (
<Autocomplete
className={containerClassName}
options={data}
disabled={disabled}
onOpen={() => {
Expand Down
4 changes: 4 additions & 0 deletions src/components/form/ComboBox/ComboBoxField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ interface ComboBoxFieldProps extends Omit<ComboBoxProps, 'onChange' | 'value' |
// eslint-disable-next-line @typescript-eslint/no-explicit-any
formikProps: FormikProps<any>
isEmptyNull?: Boolean // If false, on field reset the combobox will return an empty string
containerClassName?: string
}

export const ComboBoxField = memo(
Expand All @@ -20,12 +21,14 @@ export const ComboBoxField = memo(
formikProps,
renderGroupHeader,
data,
containerClassName,
...props
}: ComboBoxFieldProps) => {
const { setFieldValue, values, errors, touched } = formikProps

return renderGroupHeader ? (
<ComboBox
containerClassName={containerClassName}
name={name}
data={data as ComboboxDataGrouped[]}
renderGroupHeader={renderGroupHeader}
Expand All @@ -36,6 +39,7 @@ export const ComboBoxField = memo(
/>
) : (
<ComboBox
containerClassName={containerClassName}
data={data as BasicComboBoxData[]}
name={name}
value={_get(values, name)}
Expand Down
1 change: 1 addition & 0 deletions src/components/form/ComboBox/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ interface BasicComboboxProps extends Omit<ComboBoxInputProps, 'params' | 'search
searchTerm?: InputMaybe<string> | undefined
}>
>
containerClassName?: string
}

interface GroupedComboboxProps extends Omit<BasicComboboxProps, 'data' | 'renderGroupHeader'> {
Expand Down
79 changes: 77 additions & 2 deletions src/generated/graphql.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,14 @@ export type AnrokIntegration = {
name: Scalars['String']['output'];
};

export type ApiKey = {
__typename?: 'ApiKey';
createdAt: Scalars['ISO8601DateTime']['output'];
expiresAt?: Maybe<Scalars['ISO8601DateTime']['output']>;
id: Scalars['ID']['output'];
value: Scalars['String']['output'];
};

export type AppliedAddOn = {
__typename?: 'AppliedAddOn';
addOn: AddOn;
Expand Down Expand Up @@ -245,6 +253,8 @@ export type BillableMetric = {
organization?: Maybe<Organization>;
plansCount: Scalars['Int']['output'];
recurring: Scalars['Boolean']['output'];
roundingFunction?: Maybe<RoundingFunctionEnum>;
roundingPrecision?: Maybe<Scalars['Int']['output']>;
subscriptionsCount: Scalars['Int']['output'];
updatedAt: Scalars['ISO8601DateTime']['output'];
weightedInterval?: Maybe<WeightedIntervalEnum>;
Expand Down Expand Up @@ -1054,6 +1064,8 @@ export type CreateBillableMetricInput = {
filters?: InputMaybe<Array<BillableMetricFiltersInput>>;
name: Scalars['String']['input'];
recurring?: InputMaybe<Scalars['Boolean']['input']>;
roundingFunction?: InputMaybe<RoundingFunctionEnum>;
roundingPrecision?: InputMaybe<Scalars['Int']['input']>;
weightedInterval?: InputMaybe<WeightedIntervalEnum>;
};

Expand Down Expand Up @@ -1494,6 +1506,8 @@ export enum CurrencyEnum {
Bdt = 'BDT',
/** Bulgarian Lev */
Bgn = 'BGN',
/** Bahraini Dinar */
Bhd = 'BHD',
/** Burundian Franc */
Bif = 'BIF',
/** Bermudian Dollar */
Expand Down Expand Up @@ -1755,6 +1769,7 @@ export type CurrentOrganization = {
addressLine2?: Maybe<Scalars['String']['output']>;
adyenPaymentProviders?: Maybe<Array<AdyenProvider>>;
apiKey?: Maybe<Scalars['String']['output']>;
appliedDunningCampaign?: Maybe<DunningCampaign>;
billingConfiguration?: Maybe<OrganizationBillingConfiguration>;
city?: Maybe<Scalars['String']['output']>;
country?: Maybe<CountryCode>;
Expand Down Expand Up @@ -2725,6 +2740,7 @@ export enum IntegrationTypeEnum {
Netsuite = 'netsuite',
Okta = 'okta',
ProgressiveBilling = 'progressive_billing',
RevenueAnalytics = 'revenue_analytics',
Xero = 'xero'
}

Expand Down Expand Up @@ -3244,6 +3260,8 @@ export type Mutation = {
revokeInvite?: Maybe<Invite>;
/** Revoke a membership */
revokeMembership?: Maybe<Membership>;
/** Create new ApiKey while expiring provided */
rotateApiKey?: Maybe<ApiKey>;
/** Sync crm integration invoice */
syncCrmIntegrationInvoice?: Maybe<SyncCrmIntegrationInvoicePayload>;
/** Sync integration credit note */
Expand Down Expand Up @@ -3684,6 +3702,11 @@ export type MutationRevokeMembershipArgs = {
};


export type MutationRotateApiKeyArgs = {
input: RotateApiKeyInput;
};


export type MutationSyncCrmIntegrationInvoiceArgs = {
input: SyncCrmIntegrationInvoiceInput;
};
Expand Down Expand Up @@ -4103,6 +4126,7 @@ export type Plan = {
customersCount: Scalars['Int']['output'];
description?: Maybe<Scalars['String']['output']>;
draftInvoicesCount: Scalars['Int']['output'];
hasOverriddenPlans?: Maybe<Scalars['Boolean']['output']>;
id: Scalars['ID']['output'];
interval: PlanInterval;
invoiceDisplayName?: Maybe<Scalars['String']['output']>;
Expand Down Expand Up @@ -4153,6 +4177,7 @@ export enum PremiumIntegrationTypeEnum {
Netsuite = 'netsuite',
Okta = 'okta',
ProgressiveBilling = 'progressive_billing',
RevenueAnalytics = 'revenue_analytics',
Xero = 'xero'
}

Expand Down Expand Up @@ -4225,6 +4250,10 @@ export type Query = {
addOn?: Maybe<AddOn>;
/** Query add-ons of an organization */
addOns: AddOnCollection;
/** Query the API key */
apiKey: ApiKey;
/** Query the API keys of current organization */
apiKeys: SanitizedApiKeyCollection;
/** Query a single billable metric of an organization */
billableMetric?: Maybe<BillableMetric>;
/** Query billable metrics of an organization */
Expand Down Expand Up @@ -4362,6 +4391,17 @@ export type QueryAddOnsArgs = {
};


export type QueryApiKeyArgs = {
id: Scalars['ID']['input'];
};


export type QueryApiKeysArgs = {
limit?: InputMaybe<Scalars['Int']['input']>;
page?: InputMaybe<Scalars['Int']['input']>;
};


export type QueryBillableMetricArgs = {
id: Scalars['ID']['input'];
};
Expand Down Expand Up @@ -4870,6 +4910,36 @@ export type RevokeMembershipInput = {
id: Scalars['ID']['input'];
};

/** Autogenerated input type of RotateApiKey */
export type RotateApiKeyInput = {
/** A unique identifier for the client performing the mutation. */
clientMutationId?: InputMaybe<Scalars['String']['input']>;
id: Scalars['ID']['input'];
};

export enum RoundingFunctionEnum {
Ceil = 'ceil',
Floor = 'floor',
Round = 'round'
}

export type SanitizedApiKey = {
__typename?: 'SanitizedApiKey';
createdAt: Scalars['ISO8601DateTime']['output'];
expiresAt?: Maybe<Scalars['ISO8601DateTime']['output']>;
id: Scalars['ID']['output'];
value: Scalars['String']['output'];
};

/** SanitizedApiKeyCollection type */
export type SanitizedApiKeyCollection = {
__typename?: 'SanitizedApiKeyCollection';
/** A collection of paginated SanitizedApiKeyCollection */
collection: Array<SanitizedApiKey>;
/** Pagination Metadata for navigating the Pagination */
metadata: CollectionMetadata;
};

export enum StatusTypeEnum {
Active = 'active',
Canceled = 'canceled',
Expand Down Expand Up @@ -5395,6 +5465,8 @@ export type UpdateBillableMetricInput = {
id: Scalars['String']['input'];
name: Scalars['String']['input'];
recurring?: InputMaybe<Scalars['Boolean']['input']>;
roundingFunction?: InputMaybe<RoundingFunctionEnum>;
roundingPrecision?: InputMaybe<Scalars['Int']['input']>;
weightedInterval?: InputMaybe<WeightedIntervalEnum>;
};

Expand Down Expand Up @@ -5654,6 +5726,7 @@ export type UpdatePlanInput = {
amountCents: Scalars['BigInt']['input'];
amountCurrency: CurrencyEnum;
billChargesMonthly?: InputMaybe<Scalars['Boolean']['input']>;
cascadeUpdates?: InputMaybe<Scalars['Boolean']['input']>;
charges: Array<ChargeInput>;
/** A unique identifier for the client performing the mutation. */
clientMutationId?: InputMaybe<Scalars['String']['input']>;
Expand Down Expand Up @@ -7659,7 +7732,7 @@ export type GetSingleBillableMetricQueryVariables = Exact<{
}>;


export type GetSingleBillableMetricQuery = { __typename?: 'Query', billableMetric?: { __typename?: 'BillableMetric', id: string, name: string, code: string, expression?: string | null, description?: string | null, aggregationType: AggregationTypeEnum, fieldName?: string | null, subscriptionsCount: number, plansCount: number, recurring: boolean, filters?: Array<{ __typename?: 'BillableMetricFilter', key: string, values: Array<string> }> | null } | null };
export type GetSingleBillableMetricQuery = { __typename?: 'Query', billableMetric?: { __typename?: 'BillableMetric', id: string, name: string, code: string, expression?: string | null, description?: string | null, aggregationType: AggregationTypeEnum, fieldName?: string | null, subscriptionsCount: number, plansCount: number, recurring: boolean, roundingFunction?: RoundingFunctionEnum | null, roundingPrecision?: number | null, filters?: Array<{ __typename?: 'BillableMetricFilter', key: string, values: Array<string> }> | null } | null };

export type CreateBillableMetricMutationVariables = Exact<{
input: CreateBillableMetricInput;
Expand Down Expand Up @@ -7888,7 +7961,7 @@ export type GetTaxesForAddOnFormQueryVariables = Exact<{

export type GetTaxesForAddOnFormQuery = { __typename?: 'Query', taxes: { __typename?: 'TaxCollection', metadata: { __typename?: 'CollectionMetadata', currentPage: number, totalPages: number }, collection: Array<{ __typename?: 'Tax', id: string, name: string, rate: number, code: string }> } };

export type EditBillableMetricFragment = { __typename?: 'BillableMetric', id: string, name: string, code: string, expression?: string | null, description?: string | null, aggregationType: AggregationTypeEnum, fieldName?: string | null, subscriptionsCount: number, plansCount: number, recurring: boolean, filters?: Array<{ __typename?: 'BillableMetricFilter', key: string, values: Array<string> }> | null };
export type EditBillableMetricFragment = { __typename?: 'BillableMetric', id: string, name: string, code: string, expression?: string | null, description?: string | null, aggregationType: AggregationTypeEnum, fieldName?: string | null, subscriptionsCount: number, plansCount: number, recurring: boolean, roundingFunction?: RoundingFunctionEnum | null, roundingPrecision?: number | null, filters?: Array<{ __typename?: 'BillableMetricFilter', key: string, values: Array<string> }> | null };

export type CreateCreditNoteInvoiceFragment = { __typename?: 'Invoice', id: string, currency?: CurrencyEnum | null, number: string, paymentStatus: InvoicePaymentStatusTypeEnum, creditableAmountCents: any, refundableAmountCents: any, subTotalIncludingTaxesAmountCents: any, availableToCreditAmountCents: any, paymentDisputeLostAt?: any | null, invoiceType: InvoiceTypeEnum, couponsAmountCents: any, feesAmountCents: any, versionNumber: number, fees?: Array<{ __typename?: 'Fee', id: string, appliedTaxes?: Array<{ __typename?: 'FeeAppliedTax', id: string, taxName: string, taxRate: number }> | null }> | null };

Expand Down Expand Up @@ -10681,6 +10754,8 @@ export const EditBillableMetricFragmentDoc = gql`
subscriptionsCount
plansCount
recurring
roundingFunction
roundingPrecision
filters {
key
values
Expand Down
2 changes: 2 additions & 0 deletions src/hooks/useCreateEditBillableMetric.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ export const useCreateEditBillableMetric: () => UseCreateEditBillableMetricRetur
const mutationInput = (values: CreateBillableMetricInput | UpdateBillableMetricInput) => {
return {
...values,
roundingPrecision: values.roundingPrecision ? Number(values.roundingPrecision) : null,
roundingFunction: values.roundingFunction ?? null,
weightedInterval:
values.aggregationType === AggregationTypeEnum.WeightedSumAgg
? WeightedIntervalEnum.Seconds
Expand Down
Loading
Loading