feat(sdk-ts): payment links sdk ts utils
This commit is contained in:
@@ -14,6 +14,7 @@ import {
|
||||
ApiExtraModels,
|
||||
ApiOperation,
|
||||
ApiParam,
|
||||
ApiQuery,
|
||||
ApiResponse,
|
||||
ApiTags,
|
||||
getSchemaPath,
|
||||
@@ -92,7 +93,7 @@ export class BillPaymentsController {
|
||||
summary:
|
||||
'Retrieves the payable entries of the new page once vendor be selected.',
|
||||
})
|
||||
@ApiParam({
|
||||
@ApiQuery({
|
||||
name: 'vendorId',
|
||||
required: true,
|
||||
type: Number,
|
||||
|
||||
@@ -24,6 +24,7 @@ import { CreditNoteApplication } from './CreditNoteApplication.service';
|
||||
import { ICreditNotesQueryDTO } from './types/CreditNotes.types';
|
||||
import { CreateCreditNoteDto, EditCreditNoteDto } from './dtos/CreditNote.dto';
|
||||
import { CreditNoteResponseDto } from './dtos/CreditNoteResponse.dto';
|
||||
import { CreditNoteStateResponseDto } from './dtos/CreditNoteStateResponse.dto';
|
||||
import { PaginatedResponseDto } from '@/common/dtos/PaginatedResults.dto';
|
||||
import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders';
|
||||
import {
|
||||
@@ -62,7 +63,11 @@ export class CreditNotesController {
|
||||
@Get('state')
|
||||
@RequirePermission(CreditNoteAction.View, AbilitySubject.CreditNote)
|
||||
@ApiOperation({ summary: 'Get credit note state' })
|
||||
@ApiResponse({ status: 200, description: 'Returns the credit note state' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Returns the credit note state',
|
||||
type: CreditNoteStateResponseDto,
|
||||
})
|
||||
getCreditNoteState() {
|
||||
return this.creditNoteApplication.getCreditNoteState();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class CreditNoteStateResponseDto {
|
||||
@ApiProperty({
|
||||
description: 'Default PDF template ID for credit notes',
|
||||
example: 1,
|
||||
})
|
||||
defaultTemplateId: number;
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Controller, Get, Query } from '@nestjs/common';
|
||||
import { GetItemsInventoryValuationListService } from './queries/GetItemsInventoryValuationList.service';
|
||||
import { GetInventoyItemsCostQueryDto } from './dtos/GetInventoryItemsCostQuery.dto';
|
||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||
import { GetInventoryItemsCostResponseDto } from './dtos/GetInventoryItemsCostResponse.dto';
|
||||
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||
import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders';
|
||||
|
||||
@Controller('inventory-cost')
|
||||
@@ -14,9 +15,14 @@ export class InventoryCostController {
|
||||
|
||||
@Get('items')
|
||||
@ApiOperation({ summary: 'Get items inventory valuation list' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Items inventory cost list',
|
||||
type: GetInventoryItemsCostResponseDto,
|
||||
})
|
||||
async getItemsCost(
|
||||
@Query() itemsCostsQueryDto: GetInventoyItemsCostQueryDto,
|
||||
) {
|
||||
): Promise<GetInventoryItemsCostResponseDto> {
|
||||
const costs = await this.inventoryItemCost.getItemsInventoryValuationList(
|
||||
itemsCostsQueryDto.itemsIds,
|
||||
itemsCostsQueryDto.date,
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class InventoryItemCostDto {
|
||||
@ApiProperty({ description: 'Item ID' })
|
||||
itemId: number;
|
||||
|
||||
@ApiProperty({ description: 'Valuation' })
|
||||
valuation: number;
|
||||
|
||||
@ApiProperty({ description: 'Quantity' })
|
||||
quantity: number;
|
||||
|
||||
@ApiProperty({ description: 'Average cost' })
|
||||
average: number;
|
||||
}
|
||||
|
||||
export class GetInventoryItemsCostResponseDto {
|
||||
@ApiProperty({
|
||||
type: [InventoryItemCostDto],
|
||||
description: 'List of item costs',
|
||||
})
|
||||
costs: InventoryItemCostDto[];
|
||||
}
|
||||
@@ -3,6 +3,10 @@ import { Controller, Get, Param, Post, Res } from '@nestjs/common';
|
||||
import { PaymentLinksApplication } from './PaymentLinksApplication';
|
||||
import { ApiOperation, ApiParam, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||
import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders';
|
||||
import {
|
||||
GetInvoicePaymentLinkResponseWrapperDto,
|
||||
} from './dtos/GetInvoicePaymentLinkResponse.dto';
|
||||
import { CreateStripeCheckoutSessionResponseDto } from './dtos/CreateStripeCheckoutSessionResponse.dto';
|
||||
|
||||
@Controller('payment-links')
|
||||
@ApiTags('Payment Links')
|
||||
@@ -24,12 +28,7 @@ export class PaymentLinksController {
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Successfully retrieved payment link metadata',
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
data: { type: 'object', description: 'Payment link metadata' },
|
||||
},
|
||||
},
|
||||
type: GetInvoicePaymentLinkResponseWrapperDto,
|
||||
})
|
||||
@ApiResponse({ status: 404, description: 'Payment link not found' })
|
||||
public async getPaymentLinkPublicMeta(
|
||||
@@ -55,19 +54,7 @@ export class PaymentLinksController {
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Successfully created Stripe checkout session',
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
description: 'Stripe checkout session ID',
|
||||
},
|
||||
url: {
|
||||
type: 'string',
|
||||
description: 'Stripe checkout session URL',
|
||||
},
|
||||
},
|
||||
},
|
||||
type: CreateStripeCheckoutSessionResponseDto,
|
||||
})
|
||||
@ApiResponse({ status: 404, description: 'Payment link not found' })
|
||||
public async createInvoicePaymentLinkCheckoutSession(
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class CreateStripeCheckoutSessionResponseDto {
|
||||
@ApiProperty({
|
||||
description: 'Stripe checkout session ID',
|
||||
example: 'cs_test_xxx',
|
||||
})
|
||||
sessionId: string;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'Stripe publishable key for the client',
|
||||
example: 'pk_test_xxx',
|
||||
})
|
||||
publishableKey: string;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'URL to redirect the customer to complete checkout',
|
||||
example: 'https://checkout.stripe.com/c/pay/cs_test_xxx',
|
||||
})
|
||||
redirectTo: string;
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class PaymentLinkAddressDto {
|
||||
@ApiProperty({ description: 'Address line 1' })
|
||||
address_1: string;
|
||||
|
||||
@ApiProperty({ description: 'Address line 2' })
|
||||
address_2: string;
|
||||
|
||||
@ApiProperty({ description: 'Postal code' })
|
||||
postal_code: string;
|
||||
|
||||
@ApiProperty({ description: 'City' })
|
||||
city: string;
|
||||
|
||||
@ApiProperty({ description: 'State or province' })
|
||||
state_province: string;
|
||||
|
||||
@ApiProperty({ description: 'Phone number' })
|
||||
phone: string;
|
||||
}
|
||||
|
||||
export class PaymentLinkOrganizationDto {
|
||||
@ApiProperty({ type: 'object', description: 'Organization address' })
|
||||
address: Record<string, PaymentLinkAddressDto>;
|
||||
|
||||
@ApiProperty({ description: 'Organization name' })
|
||||
name: string;
|
||||
|
||||
@ApiProperty({ description: 'Primary brand color' })
|
||||
primaryColor: string;
|
||||
|
||||
@ApiProperty({ description: 'Logo URI' })
|
||||
logoUri: string;
|
||||
|
||||
@ApiProperty({ description: 'Formatted address text' })
|
||||
addressTextFormatted: string;
|
||||
}
|
||||
|
||||
export class PaymentLinkEntryDto {
|
||||
@ApiProperty({ description: 'Line item description' })
|
||||
description: string;
|
||||
|
||||
@ApiProperty({ description: 'Item name' })
|
||||
itemName: string;
|
||||
|
||||
@ApiProperty({ description: 'Quantity' })
|
||||
quantity: number;
|
||||
|
||||
@ApiProperty({ description: 'Formatted quantity' })
|
||||
quantityFormatted: string;
|
||||
|
||||
@ApiProperty({ description: 'Unit rate' })
|
||||
rate: number;
|
||||
|
||||
@ApiProperty({ description: 'Formatted rate' })
|
||||
rateFormatted: string;
|
||||
|
||||
@ApiProperty({ description: 'Line total' })
|
||||
total: number;
|
||||
|
||||
@ApiProperty({ description: 'Formatted total' })
|
||||
totalFormatted: string;
|
||||
}
|
||||
|
||||
export class PaymentLinkTaxEntryDto {
|
||||
@ApiProperty({ description: 'Tax name' })
|
||||
name: string;
|
||||
|
||||
@ApiProperty({ description: 'Tax rate amount' })
|
||||
taxRateAmount: number;
|
||||
|
||||
@ApiProperty({ description: 'Formatted tax rate amount' })
|
||||
taxRateAmountFormatted: string;
|
||||
|
||||
@ApiProperty({ description: 'Tax rate code' })
|
||||
taxRateCode: string;
|
||||
}
|
||||
|
||||
export class PaymentLinkBrandingTemplateDto {
|
||||
@ApiProperty({ description: 'Company logo URI' })
|
||||
companyLogoUri: string;
|
||||
|
||||
@ApiProperty({ description: 'Primary color' })
|
||||
primaryColor: string;
|
||||
|
||||
@ApiProperty({ description: 'Secondary color', required: false })
|
||||
secondaryColor?: string;
|
||||
}
|
||||
|
||||
export class GetInvoicePaymentLinkResponseDto {
|
||||
@ApiProperty({ description: 'Amount due' })
|
||||
dueAmount: number;
|
||||
|
||||
@ApiProperty({ description: 'Formatted amount due' })
|
||||
dueAmountFormatted: string;
|
||||
|
||||
@ApiProperty({ description: 'Due date' })
|
||||
dueDate: string;
|
||||
|
||||
@ApiProperty({ description: 'Formatted due date' })
|
||||
dueDateFormatted: string;
|
||||
|
||||
@ApiProperty({ description: 'Formatted invoice date' })
|
||||
invoiceDateFormatted: string;
|
||||
|
||||
@ApiProperty({ description: 'Invoice number' })
|
||||
invoiceNo: string;
|
||||
|
||||
@ApiProperty({ description: 'Payment amount' })
|
||||
paymentAmount: number;
|
||||
|
||||
@ApiProperty({ description: 'Formatted payment amount' })
|
||||
paymentAmountFormatted: string;
|
||||
|
||||
@ApiProperty({ description: 'Subtotal' })
|
||||
subtotal: number;
|
||||
|
||||
@ApiProperty({ description: 'Formatted subtotal' })
|
||||
subtotalFormatted: string;
|
||||
|
||||
@ApiProperty({ description: 'Formatted subtotal in local currency' })
|
||||
subtotalLocalFormatted: string;
|
||||
|
||||
@ApiProperty({ description: 'Total amount' })
|
||||
total: number;
|
||||
|
||||
@ApiProperty({ description: 'Formatted total' })
|
||||
totalFormatted: string;
|
||||
|
||||
@ApiProperty({ description: 'Formatted total in local currency' })
|
||||
totalLocalFormatted: string;
|
||||
|
||||
@ApiProperty({ description: 'Customer name' })
|
||||
customerName: string;
|
||||
|
||||
@ApiProperty({ description: 'Invoice message' })
|
||||
invoiceMessage: string;
|
||||
|
||||
@ApiProperty({ description: 'Terms and conditions' })
|
||||
termsConditions: string;
|
||||
|
||||
@ApiProperty({ type: [PaymentLinkEntryDto], description: 'Invoice line entries' })
|
||||
entries: PaymentLinkEntryDto[];
|
||||
|
||||
@ApiProperty({ type: [PaymentLinkTaxEntryDto], description: 'Tax entries' })
|
||||
taxes: PaymentLinkTaxEntryDto[];
|
||||
|
||||
@ApiProperty({ type: PaymentLinkBrandingTemplateDto, description: 'Branding template' })
|
||||
brandingTemplate: PaymentLinkBrandingTemplateDto;
|
||||
|
||||
@ApiProperty({ type: PaymentLinkOrganizationDto, description: 'Organization metadata' })
|
||||
organization: PaymentLinkOrganizationDto;
|
||||
|
||||
@ApiProperty({ description: 'Whether Stripe is available as payment method' })
|
||||
hasStripePaymentMethod: boolean;
|
||||
|
||||
@ApiProperty({ description: 'Whether invoice has receivable balance' })
|
||||
isReceivable: boolean;
|
||||
|
||||
@ApiProperty({ description: 'Formatted customer address' })
|
||||
formattedCustomerAddress: string;
|
||||
}
|
||||
|
||||
export class GetInvoicePaymentLinkResponseWrapperDto {
|
||||
@ApiProperty({
|
||||
type: GetInvoicePaymentLinkResponseDto,
|
||||
description: 'Payment link invoice metadata',
|
||||
})
|
||||
data: GetInvoicePaymentLinkResponseDto;
|
||||
}
|
||||
@@ -12,4 +12,12 @@ export class CreateStripeAccountLinkService {
|
||||
public createAccountLink(stripeAccountId: string) {
|
||||
return this.stripePaymentService.createAccountLink(stripeAccountId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Stripe account session for the Connect embedded component.
|
||||
* @param {string} accountId - Stripe Connect account ID.
|
||||
*/
|
||||
public createAccountSession(accountId: string) {
|
||||
return this.stripePaymentService.createAccountSession(accountId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
import { Body, Controller, Get, Injectable, Post } from '@nestjs/common';
|
||||
import { StripePaymentApplication } from './StripePaymentApplication';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||
import { GetStripeConnectLinkResponseDto } from './dtos/GetStripeConnectLinkResponse.dto';
|
||||
import { ExchangeStripeOAuthBodyDto } from './dtos/ExchangeStripeOAuthBody.dto';
|
||||
import { CreateStripeAccountLinkBodyDto } from './dtos/CreateStripeAccountLinkBody.dto';
|
||||
import { CreateStripeAccountLinkResponseDto } from './dtos/CreateStripeAccountLinkResponse.dto';
|
||||
import { CreateStripeAccountResponseDto } from './dtos/CreateStripeAccountResponse.dto';
|
||||
import { CreateStripeAccountSessionBodyDto } from './dtos/CreateStripeAccountSessionBody.dto';
|
||||
import { CreateStripeAccountSessionResponseDto } from './dtos/CreateStripeAccountSessionResponse.dto';
|
||||
|
||||
@Controller('/stripe')
|
||||
@ApiTags('stripe')
|
||||
@@ -9,9 +16,17 @@ export class StripeIntegrationController {
|
||||
|
||||
/**
|
||||
* Retrieves Stripe OAuth2 connect link.
|
||||
* @returns {Promise<Response|void>}
|
||||
*/
|
||||
@Get('/link')
|
||||
@ApiOperation({
|
||||
summary: 'Get Stripe Connect link',
|
||||
description: 'Retrieves the Stripe OAuth2 Connect authorization URL',
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Successfully retrieved Stripe Connect link',
|
||||
type: GetStripeConnectLinkResponseDto,
|
||||
})
|
||||
public async getStripeConnectLink() {
|
||||
const authorizationUri = this.stripePaymentApp.getStripeConnectLink();
|
||||
|
||||
@@ -20,37 +35,85 @@ export class StripeIntegrationController {
|
||||
|
||||
/**
|
||||
* Exchanges the given Stripe authorization code to Stripe user id and access token.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
@Post('/callback')
|
||||
public async exchangeOAuth(@Body('code') code: string) {
|
||||
await this.stripePaymentApp.exchangeStripeOAuthToken(code);
|
||||
@ApiOperation({
|
||||
summary: 'Exchange Stripe OAuth code',
|
||||
description:
|
||||
'Exchanges the Stripe authorization code for user id and access token',
|
||||
})
|
||||
@ApiBody({ type: ExchangeStripeOAuthBodyDto })
|
||||
@ApiResponse({
|
||||
status: 201,
|
||||
description: 'Successfully exchanged OAuth code',
|
||||
})
|
||||
public async exchangeOAuth(@Body() body: ExchangeStripeOAuthBodyDto) {
|
||||
await this.stripePaymentApp.exchangeStripeOAuthToken(body.code);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Stripe account.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
@Post('/account')
|
||||
@ApiOperation({
|
||||
summary: 'Create Stripe account',
|
||||
description: 'Creates a new Stripe Connect account',
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 201,
|
||||
description: 'Successfully created Stripe account',
|
||||
type: CreateStripeAccountResponseDto,
|
||||
})
|
||||
public async createAccount() {
|
||||
const accountId = await this.stripePaymentApp.createStripeAccount();
|
||||
return {
|
||||
accountId,
|
||||
message: 'The Stripe account has been created successfully.',
|
||||
};
|
||||
return { account_id: accountId };
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Stripe account session.
|
||||
* @returns {Promise<void>}
|
||||
* Creates a Stripe account session for the Connect embedded component.
|
||||
*/
|
||||
@Post('/account_session')
|
||||
@ApiOperation({
|
||||
summary: 'Create Stripe account session',
|
||||
description:
|
||||
'Creates an account session for the Stripe Connect embedded component',
|
||||
})
|
||||
@ApiBody({ type: CreateStripeAccountSessionBodyDto })
|
||||
@ApiResponse({
|
||||
status: 201,
|
||||
description: 'Successfully created account session',
|
||||
type: CreateStripeAccountSessionResponseDto,
|
||||
})
|
||||
public async createAccountSession(
|
||||
@Body() body: CreateStripeAccountSessionBodyDto,
|
||||
) {
|
||||
const clientSecret = await this.stripePaymentApp.createAccountSession(
|
||||
body.account ?? '',
|
||||
);
|
||||
return { client_secret: clientSecret };
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Stripe account link for onboarding.
|
||||
*/
|
||||
@Post('/account_link')
|
||||
@ApiOperation({
|
||||
summary: 'Create Stripe account link',
|
||||
description: 'Creates a Stripe Connect account link for onboarding',
|
||||
})
|
||||
@ApiBody({ type: CreateStripeAccountLinkBodyDto })
|
||||
@ApiResponse({
|
||||
status: 201,
|
||||
description: 'Successfully created account link',
|
||||
type: CreateStripeAccountLinkResponseDto,
|
||||
})
|
||||
public async createAccountLink(
|
||||
@Body('stripeAccountId') stripeAccountId: string,
|
||||
@Body() body: CreateStripeAccountLinkBodyDto,
|
||||
) {
|
||||
const clientSecret =
|
||||
await this.stripePaymentApp.createAccountLink(stripeAccountId);
|
||||
await this.stripePaymentApp.createAccountLink(body.stripeAccountId);
|
||||
|
||||
return { clientSecret };
|
||||
}
|
||||
|
||||
@@ -37,6 +37,14 @@ export class StripePaymentApplication {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Stripe account session for the Connect embedded component.
|
||||
* @param {string} accountId - Stripe Connect account ID.
|
||||
*/
|
||||
public createAccountSession(accountId: string) {
|
||||
return this.createStripeAccountLinkService.createAccountSession(accountId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves Stripe OAuth2 connect link.
|
||||
* @returns {string}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsString } from 'class-validator';
|
||||
|
||||
export class CreateStripeAccountLinkBodyDto {
|
||||
@ApiProperty({
|
||||
description: 'Stripe Connect account ID',
|
||||
example: 'acct_xxx',
|
||||
})
|
||||
@IsString()
|
||||
stripeAccountId: string;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { StripeAccountLinkResponseDto } from './StripeAccountLinkResponse.dto';
|
||||
|
||||
export class CreateStripeAccountLinkResponseDto {
|
||||
@ApiProperty({
|
||||
type: StripeAccountLinkResponseDto,
|
||||
description: 'Stripe AccountLink object for onboarding',
|
||||
})
|
||||
clientSecret: StripeAccountLinkResponseDto;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class CreateStripeAccountResponseDto {
|
||||
@ApiProperty({
|
||||
description: 'The Stripe Connect account ID',
|
||||
example: 'acct_1234567890',
|
||||
})
|
||||
account_id: string;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class CreateStripeAccountSessionBodyDto {
|
||||
@ApiProperty({
|
||||
description: 'Stripe Connect account ID to create a session for',
|
||||
example: 'acct_1234567890',
|
||||
required: false,
|
||||
})
|
||||
account?: string;
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class CreateStripeAccountSessionResponseDto {
|
||||
@ApiProperty({
|
||||
description: 'Stripe Account Session client secret for the Connect embedded component',
|
||||
example: 'acs_xxx_secret_xxx',
|
||||
})
|
||||
client_secret: string;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsString } from 'class-validator';
|
||||
|
||||
export class ExchangeStripeOAuthBodyDto {
|
||||
@ApiProperty({
|
||||
description: 'Authorization code returned by Stripe OAuth',
|
||||
example: 'ac_xxx',
|
||||
})
|
||||
@IsString()
|
||||
code: string;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class GetStripeConnectLinkResponseDto {
|
||||
@ApiProperty({
|
||||
description: 'Stripe OAuth2 Connect authorization URL',
|
||||
example: 'https://connect.stripe.com/oauth/authorize?response_type=code&client_id=...',
|
||||
})
|
||||
url: string;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class StripeAccountLinkResponseDto {
|
||||
@ApiProperty({
|
||||
description: 'URL for the account onboarding flow',
|
||||
example: 'https://connect.stripe.com/setup/xxx',
|
||||
})
|
||||
url: string;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'Unix timestamp when the link was created',
|
||||
example: 1234567890,
|
||||
})
|
||||
created: number;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'Unix timestamp when the link expires',
|
||||
example: 1234567890,
|
||||
})
|
||||
expires_at: number;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'Stripe object type',
|
||||
example: 'account_link',
|
||||
})
|
||||
object: string;
|
||||
}
|
||||
@@ -276,10 +276,11 @@ export async function uncategorizeTransactionsBulk(
|
||||
const del = fetcher
|
||||
.path(BANK_RULES_ROUTES.CATEGORIZE_BULK)
|
||||
.method('delete')
|
||||
.create();
|
||||
await (del as (params: {
|
||||
query?: { uncategorizedTransactionIds: number[] };
|
||||
}) => Promise<unknown>)({
|
||||
query: { uncategorizedTransactionIds },
|
||||
});
|
||||
.create(
|
||||
{ uncategorizedTransactionIds } as unknown as {
|
||||
uncategorizedTransactionIds: true | 1;
|
||||
},
|
||||
);
|
||||
// create() binds query; call with no args (params were passed to create())
|
||||
await (del as unknown as () => Promise<unknown>)();
|
||||
}
|
||||
|
||||
@@ -44,9 +44,17 @@ export async function fetchCreditNote(fetcher: ApiFetcher, id: number): Promise<
|
||||
return data;
|
||||
}
|
||||
|
||||
export async function fetchCreditNoteState(fetcher: ApiFetcher): Promise<void> {
|
||||
/** Credit note state (default template etc.). Defined in controller DTO when not in schema. */
|
||||
export interface CreditNoteStateResponse {
|
||||
defaultTemplateId: number;
|
||||
}
|
||||
|
||||
export async function fetchCreditNoteState(
|
||||
fetcher: ApiFetcher
|
||||
): Promise<CreditNoteStateResponse> {
|
||||
const getState = fetcher.path(CREDIT_NOTES_ROUTES.STATE).method('get').create();
|
||||
await getState({});
|
||||
const { data } = await getState({});
|
||||
return (data ?? { defaultTemplateId: 0 }) as CreditNoteStateResponse;
|
||||
}
|
||||
|
||||
export async function createCreditNote(
|
||||
|
||||
@@ -17,6 +17,8 @@ export type EditCustomerBody = OpRequestBody<OpForPath<typeof CUSTOMERS_ROUTES.B
|
||||
export type ValidateBulkDeleteCustomersResponse = OpResponseBody<OpForPath<typeof CUSTOMERS_ROUTES.VALIDATE_BULK_DELETE, 'post'>>;
|
||||
export type BulkDeleteCustomersBody = OpRequestBody<OpForPath<typeof CUSTOMERS_ROUTES.BULK_DELETE, 'post'>>;
|
||||
export type GetCustomersQuery = OpQueryParams<OpForPath<typeof CUSTOMERS_ROUTES.LIST, 'get'>>;
|
||||
export type EditCustomerOpeningBalanceBody = OpRequestBody<OpForPath<typeof CUSTOMERS_ROUTES.OPENING_BALANCE, 'put'>>;
|
||||
export type EditCustomerOpeningBalanceResponse = OpResponseBody<OpForPath<typeof CUSTOMERS_ROUTES.OPENING_BALANCE, 'put'>>;
|
||||
|
||||
export async function fetchCustomers(
|
||||
fetcher: ApiFetcher,
|
||||
@@ -73,3 +75,13 @@ export async function bulkDeleteCustomers(
|
||||
const post = fetcher.path(CUSTOMERS_ROUTES.BULK_DELETE).method('post').create();
|
||||
await post(body);
|
||||
}
|
||||
|
||||
export async function editCustomerOpeningBalance(
|
||||
fetcher: ApiFetcher,
|
||||
id: number,
|
||||
values: EditCustomerOpeningBalanceBody
|
||||
): Promise<EditCustomerOpeningBalanceResponse> {
|
||||
const put = fetcher.path(CUSTOMERS_ROUTES.OPENING_BALANCE).method('put').create();
|
||||
const { data } = await put({ id, ...values });
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
import type { ApiFetcher } from './fetch-utils';
|
||||
import { paths } from './schema';
|
||||
|
||||
export const IMPORT_ROUTES = {
|
||||
FILE: '/api/import/file',
|
||||
MAPPING: '/api/import/{import_id}/mapping',
|
||||
PREVIEW: '/api/import/{import_id}/preview',
|
||||
IMPORT: '/api/import/{import_id}/import',
|
||||
SAMPLE: '/api/import/sample',
|
||||
META: '/api/import/{import_id}',
|
||||
} as const satisfies Record<string, keyof paths>;
|
||||
|
||||
export interface ImportMappingBody {
|
||||
mapping: Array<{ group?: string; from: string; to: string }>;
|
||||
}
|
||||
|
||||
export interface ImportPreviewResponse {
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
export interface ImportFileMetaResponse {
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
export interface ImportProcessResponse {
|
||||
resource?: string;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
export async function fetchImportPreview(
|
||||
fetcher: ApiFetcher,
|
||||
importId: string
|
||||
): Promise<ImportPreviewResponse> {
|
||||
const get = fetcher
|
||||
.path(IMPORT_ROUTES.PREVIEW)
|
||||
.method('get')
|
||||
.create();
|
||||
const { data } = await get({ import_id: importId } as never);
|
||||
return (data ?? {}) as ImportPreviewResponse;
|
||||
}
|
||||
|
||||
export async function fetchImportFileMeta(
|
||||
fetcher: ApiFetcher,
|
||||
importId: string
|
||||
): Promise<ImportFileMetaResponse> {
|
||||
const get = fetcher.path(IMPORT_ROUTES.META).method('get').create();
|
||||
const { data } = await get({ import_id: importId } as never);
|
||||
return (data ?? {}) as ImportFileMetaResponse;
|
||||
}
|
||||
|
||||
export async function importMapping(
|
||||
fetcher: ApiFetcher,
|
||||
importId: string,
|
||||
body: ImportMappingBody
|
||||
): Promise<void> {
|
||||
const post = fetcher
|
||||
.path(IMPORT_ROUTES.MAPPING)
|
||||
.method('post')
|
||||
.create();
|
||||
await post({ import_id: importId, ...body } as never);
|
||||
}
|
||||
|
||||
export async function importProcess(
|
||||
fetcher: ApiFetcher,
|
||||
importId: string
|
||||
): Promise<ImportProcessResponse> {
|
||||
const post = fetcher.path(IMPORT_ROUTES.IMPORT).method('post').create();
|
||||
const { data } = await post({ import_id: importId } as never);
|
||||
return (data ?? {}) as ImportProcessResponse;
|
||||
}
|
||||
@@ -15,10 +15,12 @@ export * from './items';
|
||||
export * from './branches';
|
||||
export * from './warehouses';
|
||||
export * from './expenses';
|
||||
export * from './import';
|
||||
export * from './manual-journals';
|
||||
export * from './roles';
|
||||
export * from './users';
|
||||
export * from './dashboard';
|
||||
export * from './export';
|
||||
export * from './settings';
|
||||
export * from './organization';
|
||||
export * from './subscription';
|
||||
@@ -37,7 +39,12 @@ export * from './sale-estimates';
|
||||
export * from './sale-receipts';
|
||||
export * from './payment-receives';
|
||||
export * from './payment-mades';
|
||||
export * from './payment-links';
|
||||
export * from './payment-services';
|
||||
export * from './plaid';
|
||||
export * from './stripe-integration';
|
||||
export * from './inventory-adjustments';
|
||||
export * from './inventory-cost';
|
||||
export * from './warehouse-transfers';
|
||||
export * from './landed-cost';
|
||||
export * from './generic-resource';
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import type { OpArgType } from 'openapi-typescript-fetch';
|
||||
import type { ApiFetcher } from './fetch-utils';
|
||||
import { paths } from './schema';
|
||||
import { OpForPath, OpQueryParams } from './utils';
|
||||
|
||||
export const INVENTORY_COST_ROUTES = {
|
||||
ITEMS: '/api/inventory-cost/items',
|
||||
} as const satisfies Record<string, keyof paths>;
|
||||
|
||||
type GetItemsCostOp = OpForPath<typeof INVENTORY_COST_ROUTES.ITEMS, 'get'>;
|
||||
type GetItemsCostArg = OpArgType<GetItemsCostOp>;
|
||||
|
||||
/** Query params for get items inventory cost. */
|
||||
export type GetInventoryItemsCostQuery = OpQueryParams<GetItemsCostOp>;
|
||||
|
||||
export interface InventoryItemCostMeta {
|
||||
itemId: number;
|
||||
valuation: number;
|
||||
quantity: number;
|
||||
average: number;
|
||||
}
|
||||
|
||||
export interface GetInventoryItemsCostResponse {
|
||||
costs: InventoryItemCostMeta[];
|
||||
}
|
||||
|
||||
export async function fetchInventoryCostItems(
|
||||
fetcher: ApiFetcher,
|
||||
query: GetInventoryItemsCostQuery
|
||||
): Promise<GetInventoryItemsCostResponse> {
|
||||
const get = fetcher.path(INVENTORY_COST_ROUTES.ITEMS).method('get').create();
|
||||
const { data } = await get(query as GetItemsCostArg);
|
||||
return (data ?? { costs: [] }) as GetInventoryItemsCostResponse;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { ApiFetcher } from './fetch-utils';
|
||||
import { paths } from './schema';
|
||||
import { OpForPath, OpQueryParams, OpResponseBody } from './utils';
|
||||
import { OpForPath, OpQueryParams, OpRequestBody, OpResponseBody } from './utils';
|
||||
|
||||
export const LANDED_COST_ROUTES = {
|
||||
TRANSACTIONS: '/api/landed-cost/transactions',
|
||||
@@ -11,6 +11,10 @@ export const LANDED_COST_ROUTES = {
|
||||
|
||||
export type LandedCostTransactionsResponse = OpResponseBody<OpForPath<typeof LANDED_COST_ROUTES.TRANSACTIONS, 'get'>>;
|
||||
export type GetLandedCostTransactionsQuery = OpQueryParams<OpForPath<typeof LANDED_COST_ROUTES.TRANSACTIONS, 'get'>>;
|
||||
export type AllocateLandedCostBody = OpRequestBody<OpForPath<typeof LANDED_COST_ROUTES.ALLOCATE, 'post'>>;
|
||||
export type BillLandedCostTransactionsResponse = OpResponseBody<
|
||||
OpForPath<typeof LANDED_COST_ROUTES.BILL_TRANSACTIONS, 'get'>
|
||||
>;
|
||||
|
||||
export async function fetchLandedCostTransactions(
|
||||
fetcher: ApiFetcher,
|
||||
@@ -22,3 +26,29 @@ export async function fetchLandedCostTransactions(
|
||||
)(query ?? {});
|
||||
return data;
|
||||
}
|
||||
|
||||
export async function allocateLandedCost(
|
||||
fetcher: ApiFetcher,
|
||||
billId: number,
|
||||
body: AllocateLandedCostBody
|
||||
): Promise<void> {
|
||||
const post = fetcher.path(LANDED_COST_ROUTES.ALLOCATE).method('post').create();
|
||||
await post({ billId, ...body } as never);
|
||||
}
|
||||
|
||||
export async function deleteAllocatedLandedCost(
|
||||
fetcher: ApiFetcher,
|
||||
allocatedLandedCostId: number
|
||||
): Promise<void> {
|
||||
const del = fetcher.path(LANDED_COST_ROUTES.BY_ID).method('delete').create();
|
||||
await del({ allocatedLandedCostId });
|
||||
}
|
||||
|
||||
export async function fetchBillLandedCostTransactions(
|
||||
fetcher: ApiFetcher,
|
||||
billId: number
|
||||
): Promise<BillLandedCostTransactionsResponse> {
|
||||
const get = fetcher.path(LANDED_COST_ROUTES.BILL_TRANSACTIONS).method('get').create();
|
||||
const { data } = await get({ billId });
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,11 @@ export const ORGANIZATION_ROUTES = {
|
||||
|
||||
export type OrganizationCurrent = OpResponseBody<OpForPath<typeof ORGANIZATION_ROUTES.CURRENT, 'get'>>;
|
||||
export type UpdateOrganizationBody = OpRequestBody<OpForPath<typeof ORGANIZATION_ROUTES.UPDATE, 'put'>>;
|
||||
export type BuildOrganizationBody = OpRequestBody<OpForPath<typeof ORGANIZATION_ROUTES.BUILD, 'post'>>;
|
||||
export type BuildOrganizationResponse = OpResponseBody<OpForPath<typeof ORGANIZATION_ROUTES.BUILD, 'post'>>;
|
||||
export type OrgBaseCurrencyMutateAbilitiesResponse = OpResponseBody<
|
||||
OpForPath<typeof ORGANIZATION_ROUTES.BASE_CURRENCY_MUTATE, 'get'>
|
||||
>;
|
||||
|
||||
export async function fetchOrganizationCurrent(fetcher: ApiFetcher): Promise<OrganizationCurrent> {
|
||||
const get = fetcher.path(ORGANIZATION_ROUTES.CURRENT).method('get').create();
|
||||
@@ -19,6 +24,23 @@ export async function fetchOrganizationCurrent(fetcher: ApiFetcher): Promise<Org
|
||||
return data;
|
||||
}
|
||||
|
||||
export async function buildOrganization(
|
||||
fetcher: ApiFetcher,
|
||||
values: BuildOrganizationBody
|
||||
): Promise<BuildOrganizationResponse> {
|
||||
const post = fetcher.path(ORGANIZATION_ROUTES.BUILD).method('post').create();
|
||||
const { data } = await post(values as never);
|
||||
return data;
|
||||
}
|
||||
|
||||
export async function fetchOrgBaseCurrencyMutateAbilities(
|
||||
fetcher: ApiFetcher
|
||||
): Promise<OrgBaseCurrencyMutateAbilitiesResponse> {
|
||||
const get = fetcher.path(ORGANIZATION_ROUTES.BASE_CURRENCY_MUTATE).method('get').create();
|
||||
const { data } = await get({});
|
||||
return data;
|
||||
}
|
||||
|
||||
export async function updateOrganization(
|
||||
fetcher: ApiFetcher,
|
||||
values: UpdateOrganizationBody
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
import type { ApiFetcher } from './fetch-utils';
|
||||
import { paths } from './schema';
|
||||
import { OpForPath, OpResponseBody, OpResponseBodyPdf } from './utils';
|
||||
|
||||
export const PAYMENT_LINKS_ROUTES = {
|
||||
GET_INVOICE: '/api/payment-links/{paymentLinkId}/invoice',
|
||||
CREATE_STRIPE_CHECKOUT_SESSION:
|
||||
'/api/payment-links/{paymentLinkId}/stripe_checkout_session',
|
||||
GET_INVOICE_PDF: '/api/payment-links/{paymentLinkId}/invoice/pdf',
|
||||
} as const satisfies Record<string, keyof paths>;
|
||||
|
||||
type GetInvoiceOp = OpForPath<
|
||||
(typeof PAYMENT_LINKS_ROUTES)['GET_INVOICE'],
|
||||
'get'
|
||||
>;
|
||||
type CreateCheckoutSessionOp = OpForPath<
|
||||
(typeof PAYMENT_LINKS_ROUTES)['CREATE_STRIPE_CHECKOUT_SESSION'],
|
||||
'post'
|
||||
>;
|
||||
type GetInvoicePdfOp = OpForPath<
|
||||
(typeof PAYMENT_LINKS_ROUTES)['GET_INVOICE_PDF'],
|
||||
'get'
|
||||
>;
|
||||
|
||||
export type GetInvoicePaymentLinkResponse = GetInvoiceOp extends {
|
||||
responses: { 200: { content: { 'application/json': infer R } } };
|
||||
}
|
||||
? R extends { data?: infer D }
|
||||
? D
|
||||
: R
|
||||
: unknown;
|
||||
|
||||
export type CreateStripeCheckoutSessionResponse =
|
||||
OpResponseBody<CreateCheckoutSessionOp>;
|
||||
export type GetPaymentLinkInvoicePdfResponse = OpResponseBodyPdf<GetInvoicePdfOp>;
|
||||
|
||||
export async function fetchGetInvoicePaymentLink(
|
||||
fetcher: ApiFetcher,
|
||||
paymentLinkId: string,
|
||||
): Promise<GetInvoicePaymentLinkResponse> {
|
||||
const get = fetcher
|
||||
.path(PAYMENT_LINKS_ROUTES.GET_INVOICE)
|
||||
.method('get')
|
||||
.create();
|
||||
const { data } = await get({ paymentLinkId });
|
||||
const body = data as { data?: GetInvoicePaymentLinkResponse };
|
||||
return body?.data ?? (body as GetInvoicePaymentLinkResponse);
|
||||
}
|
||||
|
||||
export async function fetchCreateStripeCheckoutSession(
|
||||
fetcher: ApiFetcher,
|
||||
paymentLinkId: string,
|
||||
): Promise<CreateStripeCheckoutSessionResponse> {
|
||||
const post = fetcher
|
||||
.path(PAYMENT_LINKS_ROUTES.CREATE_STRIPE_CHECKOUT_SESSION)
|
||||
.method('post')
|
||||
.create();
|
||||
const { data } = await post({ paymentLinkId });
|
||||
return data as CreateStripeCheckoutSessionResponse;
|
||||
}
|
||||
|
||||
export async function fetchGetPaymentLinkInvoicePdf(
|
||||
fetcher: ApiFetcher,
|
||||
paymentLinkId: string,
|
||||
): Promise<Blob> {
|
||||
const get = fetcher
|
||||
.path(PAYMENT_LINKS_ROUTES.GET_INVOICE_PDF)
|
||||
.method('get')
|
||||
.create();
|
||||
const response = await get({ paymentLinkId });
|
||||
return (response.data as Blob) ?? response.data;
|
||||
}
|
||||
@@ -57,3 +57,21 @@ export async function fetchBillPaymentEditPage(
|
||||
const { data } = await get({ billPaymentId });
|
||||
return data;
|
||||
}
|
||||
|
||||
export type BillPaymentNewPageEntriesResponse = unknown;
|
||||
|
||||
export async function fetchBillPaymentNewPageEntries(
|
||||
fetcher: ApiFetcher,
|
||||
vendorId: number
|
||||
): Promise<BillPaymentNewPageEntriesResponse> {
|
||||
const get = fetcher
|
||||
.path(BILL_PAYMENTS_ROUTES.NEW_PAGE_ENTRIES)
|
||||
.method('get')
|
||||
.create();
|
||||
|
||||
const { data } = await (
|
||||
// @ts-ignore
|
||||
get as (params: { query?: { vendorId: number } }) => Promise<{ data: BillPaymentNewPageEntriesResponse }>
|
||||
)({ query: { vendorId } });
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
import type { ApiFetcher } from './fetch-utils';
|
||||
import { paths } from './schema';
|
||||
|
||||
export const PAYMENT_SERVICES_ROUTES = {
|
||||
LIST: '/api/payment-services',
|
||||
STATE: '/api/payment-services/state',
|
||||
BY_ID: '/api/payment-services/{paymentServiceId}',
|
||||
UPDATE_METHOD: '/api/payment-services/{paymentMethodId}',
|
||||
DELETE_METHOD: '/api/payment-services/{paymentMethodId}',
|
||||
} as const satisfies Record<string, keyof paths>;
|
||||
|
||||
export interface GetPaymentServicesResponse {
|
||||
payment_services?: unknown;
|
||||
}
|
||||
|
||||
export interface GetPaymentServicesStateResponse {
|
||||
stripe: {
|
||||
is_stripe_account_created: boolean;
|
||||
is_stripe_payment_enabled: boolean;
|
||||
is_stripe_payout_enabled: boolean;
|
||||
is_stripe_enabled: boolean;
|
||||
is_stripe_server_configured: boolean;
|
||||
stripe_account_id: string | null;
|
||||
stripe_payment_method_id: number | null;
|
||||
stripe_currencies: string[];
|
||||
stripe_publishable_key: string;
|
||||
stripe_auth_link: string;
|
||||
stripe_redirect_url: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface GetPaymentServiceResponse {
|
||||
data?: unknown;
|
||||
}
|
||||
|
||||
export interface EditPaymentMethodOptionsBody {
|
||||
bankAccountId?: number;
|
||||
clearningAccountId?: number;
|
||||
showVisa?: boolean;
|
||||
showMasterCard?: boolean;
|
||||
showDiscover?: boolean;
|
||||
showAmer?: boolean;
|
||||
showJcb?: boolean;
|
||||
showDiners?: boolean;
|
||||
}
|
||||
|
||||
export interface UpdatePaymentMethodBody {
|
||||
name?: string;
|
||||
options?: EditPaymentMethodOptionsBody;
|
||||
}
|
||||
|
||||
export interface UpdatePaymentMethodResponse {
|
||||
id: number;
|
||||
message: string;
|
||||
}
|
||||
|
||||
export interface DeletePaymentMethodResponse {
|
||||
id: number;
|
||||
message: string;
|
||||
}
|
||||
|
||||
export async function fetchGetPaymentServices(
|
||||
fetcher: ApiFetcher,
|
||||
): Promise<GetPaymentServicesResponse> {
|
||||
const get = fetcher
|
||||
.path(PAYMENT_SERVICES_ROUTES.LIST)
|
||||
.method('get')
|
||||
.create();
|
||||
const { data } = await get({});
|
||||
return data as GetPaymentServicesResponse;
|
||||
}
|
||||
|
||||
export async function fetchGetPaymentServicesState(
|
||||
fetcher: ApiFetcher,
|
||||
): Promise<GetPaymentServicesStateResponse> {
|
||||
const get = fetcher
|
||||
.path(PAYMENT_SERVICES_ROUTES.STATE)
|
||||
.method('get')
|
||||
.create();
|
||||
const { data } = await get({});
|
||||
const wrapped = data as { data?: GetPaymentServicesStateResponse };
|
||||
return wrapped?.data ?? (data as GetPaymentServicesStateResponse);
|
||||
}
|
||||
|
||||
export async function fetchGetPaymentService(
|
||||
fetcher: ApiFetcher,
|
||||
paymentServiceId: number,
|
||||
): Promise<GetPaymentServiceResponse> {
|
||||
const get = fetcher
|
||||
.path(PAYMENT_SERVICES_ROUTES.BY_ID)
|
||||
.method('get')
|
||||
.create();
|
||||
const { data } = await get({ paymentServiceId });
|
||||
return data as GetPaymentServiceResponse;
|
||||
}
|
||||
|
||||
export async function fetchUpdatePaymentMethod(
|
||||
fetcher: ApiFetcher,
|
||||
paymentMethodId: number,
|
||||
body: UpdatePaymentMethodBody,
|
||||
): Promise<UpdatePaymentMethodResponse> {
|
||||
const post = fetcher
|
||||
.path(PAYMENT_SERVICES_ROUTES.UPDATE_METHOD)
|
||||
.method('post')
|
||||
.create();
|
||||
const { data } = await post({ paymentMethodId, ...body } as never);
|
||||
return data as UpdatePaymentMethodResponse;
|
||||
}
|
||||
|
||||
export async function fetchDeletePaymentMethod(
|
||||
fetcher: ApiFetcher,
|
||||
paymentMethodId: number,
|
||||
): Promise<DeletePaymentMethodResponse> {
|
||||
const del = fetcher
|
||||
.path(PAYMENT_SERVICES_ROUTES.DELETE_METHOD)
|
||||
.method('delete')
|
||||
.create();
|
||||
const { data } = await del({ paymentMethodId });
|
||||
return data as DeletePaymentMethodResponse;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import type { ApiFetcher } from './fetch-utils';
|
||||
import { paths } from './schema';
|
||||
|
||||
export const PLAID_ROUTES = {
|
||||
LINK_TOKEN: '/api/banking/plaid/link-token',
|
||||
EXCHANGE_TOKEN: '/api/banking/plaid/exchange-token',
|
||||
} as const satisfies Record<string, keyof paths>;
|
||||
|
||||
export interface PlaidLinkTokenResponse {
|
||||
linkToken?: string;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
export interface PlaidExchangeTokenBody {
|
||||
publicToken: string;
|
||||
institutionId?: string;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
export async function fetchPlaidLinkToken(
|
||||
fetcher: ApiFetcher
|
||||
): Promise<PlaidLinkTokenResponse> {
|
||||
const post = fetcher
|
||||
.path(PLAID_ROUTES.LINK_TOKEN)
|
||||
.method('post')
|
||||
.create();
|
||||
const { data } = await post({});
|
||||
return (data ?? {}) as PlaidLinkTokenResponse;
|
||||
}
|
||||
|
||||
export async function fetchPlaidExchangeToken(
|
||||
fetcher: ApiFetcher,
|
||||
body: PlaidExchangeTokenBody
|
||||
): Promise<void> {
|
||||
const post = fetcher
|
||||
.path(PLAID_ROUTES.EXCHANGE_TOKEN)
|
||||
.method('post')
|
||||
.create();
|
||||
await post(body as never);
|
||||
}
|
||||
@@ -1580,6 +1580,38 @@ export interface paths {
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/stripe/account": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
post: operations["StripeIntegrationController_createAccount"];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/stripe/account_session": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
post: operations["StripeIntegrationController_createAccountSession"];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/webhooks/stripe": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
@@ -17130,6 +17162,48 @@ export interface operations {
|
||||
};
|
||||
};
|
||||
};
|
||||
StripeIntegrationController_createAccount: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
201: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": { account_id: string };
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
StripeIntegrationController_createAccountSession: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": { account?: string };
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
201: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": { client_secret: string };
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
StripePaymentWebhooksController_handleWebhook: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
import type { ApiFetcher } from './fetch-utils';
|
||||
import { paths } from './schema';
|
||||
|
||||
export const STRIPE_INTEGRATION_ROUTES = {
|
||||
GET_LINK: '/api/stripe/link',
|
||||
CALLBACK: '/api/stripe/callback',
|
||||
ACCOUNT_LINK: '/api/stripe/account_link',
|
||||
ACCOUNT: '/api/stripe/account',
|
||||
ACCOUNT_SESSION: '/api/stripe/account_session',
|
||||
} as const;
|
||||
|
||||
export interface GetStripeConnectLinkResponse {
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface ExchangeStripeOAuthBody {
|
||||
code: string;
|
||||
}
|
||||
|
||||
export interface CreateStripeAccountLinkBody {
|
||||
stripeAccountId: string;
|
||||
}
|
||||
|
||||
export interface StripeAccountLinkResponse {
|
||||
url: string;
|
||||
created: number;
|
||||
expires_at: number;
|
||||
object: string;
|
||||
}
|
||||
|
||||
export interface CreateStripeAccountLinkResponse {
|
||||
clientSecret: StripeAccountLinkResponse;
|
||||
}
|
||||
|
||||
export async function fetchGetStripeConnectLink(
|
||||
fetcher: ApiFetcher,
|
||||
): Promise<GetStripeConnectLinkResponse> {
|
||||
const get = fetcher
|
||||
.path(STRIPE_INTEGRATION_ROUTES.GET_LINK)
|
||||
.method('get')
|
||||
.create();
|
||||
const { data } = await get({});
|
||||
return data as GetStripeConnectLinkResponse;
|
||||
}
|
||||
|
||||
export async function fetchExchangeStripeOAuth(
|
||||
fetcher: ApiFetcher,
|
||||
body: ExchangeStripeOAuthBody,
|
||||
): Promise<void> {
|
||||
const post = fetcher
|
||||
.path(STRIPE_INTEGRATION_ROUTES.CALLBACK)
|
||||
.method('post')
|
||||
.create();
|
||||
await post(body as never);
|
||||
}
|
||||
|
||||
export async function fetchCreateStripeAccountLink(
|
||||
fetcher: ApiFetcher,
|
||||
body: CreateStripeAccountLinkBody,
|
||||
): Promise<CreateStripeAccountLinkResponse> {
|
||||
const post = fetcher
|
||||
.path(STRIPE_INTEGRATION_ROUTES.ACCOUNT_LINK)
|
||||
.method('post')
|
||||
.create();
|
||||
const { data } = await post(body as never);
|
||||
return data as CreateStripeAccountLinkResponse;
|
||||
}
|
||||
|
||||
export interface CreateStripeAccountResponse {
|
||||
account_id: string;
|
||||
}
|
||||
|
||||
export interface CreateStripeAccountSessionBody {
|
||||
account?: string;
|
||||
}
|
||||
|
||||
export interface CreateStripeAccountSessionResponse {
|
||||
client_secret: string;
|
||||
}
|
||||
|
||||
export async function fetchCreateStripeAccount(
|
||||
fetcher: ApiFetcher,
|
||||
): Promise<CreateStripeAccountResponse> {
|
||||
const post = fetcher
|
||||
.path(STRIPE_INTEGRATION_ROUTES.ACCOUNT)
|
||||
.method('post')
|
||||
.create();
|
||||
const { data } = await post({});
|
||||
return data as CreateStripeAccountResponse;
|
||||
}
|
||||
|
||||
export async function fetchCreateStripeAccountSession(
|
||||
fetcher: ApiFetcher,
|
||||
body: CreateStripeAccountSessionBody,
|
||||
): Promise<CreateStripeAccountSessionResponse> {
|
||||
const post = fetcher
|
||||
.path(STRIPE_INTEGRATION_ROUTES.ACCOUNT_SESSION)
|
||||
.method('post')
|
||||
.create();
|
||||
const { data } = await post(body as never);
|
||||
return data as CreateStripeAccountSessionResponse;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { ApiFetcher } from './fetch-utils';
|
||||
import { paths } from './schema';
|
||||
import { OpForPath, OpResponseBody } from './utils';
|
||||
import { OpForPath, OpRequestBody, OpResponseBody } from './utils';
|
||||
|
||||
export const SUBSCRIPTION_ROUTES = {
|
||||
LIST: '/api/subscription',
|
||||
@@ -11,6 +11,9 @@ export const SUBSCRIPTION_ROUTES = {
|
||||
} as const satisfies Record<string, keyof paths>;
|
||||
|
||||
export type SubscriptionsListResponse = OpResponseBody<OpForPath<typeof SUBSCRIPTION_ROUTES.LIST, 'get'>>;
|
||||
export type ChangeSubscriptionPlanBody = OpRequestBody<OpForPath<typeof SUBSCRIPTION_ROUTES.CHANGE, 'post'>>;
|
||||
export type GetLemonCheckoutUrlBody = OpRequestBody<OpForPath<typeof SUBSCRIPTION_ROUTES.CHECKOUT_URL, 'post'>>;
|
||||
export type GetLemonCheckoutUrlResponse = OpResponseBody<OpForPath<typeof SUBSCRIPTION_ROUTES.CHECKOUT_URL, 'post'>>;
|
||||
|
||||
export async function fetchSubscriptions(fetcher: ApiFetcher): Promise<SubscriptionsListResponse> {
|
||||
const get = fetcher.path(SUBSCRIPTION_ROUTES.LIST).method('get').create();
|
||||
@@ -18,6 +21,15 @@ export async function fetchSubscriptions(fetcher: ApiFetcher): Promise<Subscript
|
||||
return data;
|
||||
}
|
||||
|
||||
export async function getLemonCheckoutUrl(
|
||||
fetcher: ApiFetcher,
|
||||
body: GetLemonCheckoutUrlBody
|
||||
): Promise<GetLemonCheckoutUrlResponse> {
|
||||
const post = fetcher.path(SUBSCRIPTION_ROUTES.CHECKOUT_URL).method('post').create();
|
||||
const { data } = await post(body as never);
|
||||
return data;
|
||||
}
|
||||
|
||||
export async function cancelSubscription(fetcher: ApiFetcher): Promise<void> {
|
||||
const post = fetcher.path(SUBSCRIPTION_ROUTES.CANCEL).method('post').create();
|
||||
await post({});
|
||||
@@ -27,3 +39,11 @@ export async function resumeSubscription(fetcher: ApiFetcher): Promise<void> {
|
||||
const post = fetcher.path(SUBSCRIPTION_ROUTES.RESUME).method('post').create();
|
||||
await post({});
|
||||
}
|
||||
|
||||
export async function changeSubscriptionPlan(
|
||||
fetcher: ApiFetcher,
|
||||
body: ChangeSubscriptionPlanBody
|
||||
): Promise<void> {
|
||||
const post = fetcher.path(SUBSCRIPTION_ROUTES.CHANGE).method('post').create();
|
||||
await post(body as never);
|
||||
}
|
||||
|
||||
@@ -154,7 +154,7 @@ export async function fetchRefundVendorCreditTransaction(
|
||||
.path(VENDOR_CREDITS_ROUTES.REFUND_BY_ID)
|
||||
.method('get')
|
||||
.create();
|
||||
const { data } = await get({ refundCreditId });
|
||||
const { data } = await get({ refundCreditId: String(refundCreditId) });
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@ export type EditVendorBody = OpRequestBody<OpForPath<typeof VENDORS_ROUTES.BY_ID
|
||||
export type ValidateBulkDeleteVendorsResponse = OpResponseBody<OpForPath<typeof VENDORS_ROUTES.VALIDATE_BULK_DELETE, 'post'>>;
|
||||
export type BulkDeleteVendorsBody = OpRequestBody<OpForPath<typeof VENDORS_ROUTES.BULK_DELETE, 'post'>>;
|
||||
export type GetVendorsQuery = OpQueryParams<OpForPath<typeof VENDORS_ROUTES.LIST, 'get'>>;
|
||||
export type EditVendorOpeningBalanceBody = OpRequestBody<OpForPath<typeof VENDORS_ROUTES.OPENING_BALANCE, 'put'>>;
|
||||
export type EditVendorOpeningBalanceResponse = OpResponseBody<OpForPath<typeof VENDORS_ROUTES.OPENING_BALANCE, 'put'>>;
|
||||
|
||||
export async function fetchVendors(
|
||||
fetcher: ApiFetcher,
|
||||
@@ -73,3 +75,13 @@ export async function bulkDeleteVendors(
|
||||
const post = fetcher.path(VENDORS_ROUTES.BULK_DELETE).method('post').create();
|
||||
await post(body);
|
||||
}
|
||||
|
||||
export async function editVendorOpeningBalance(
|
||||
fetcher: ApiFetcher,
|
||||
id: number,
|
||||
values: EditVendorOpeningBalanceBody
|
||||
): Promise<EditVendorOpeningBalanceResponse> {
|
||||
const put = fetcher.path(VENDORS_ROUTES.OPENING_BALANCE).method('put').create();
|
||||
const { data } = await put({ id, ...values });
|
||||
return data;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user