1
0

Merge pull request #1033 from bigcapitalhq/feat/credit-note-sdk-ts-utils

feat: add response DTOs for credit note modules and SDK types
This commit is contained in:
Ahmed Bouhuolia
2026-03-09 07:18:36 +02:00
committed by GitHub
19 changed files with 330 additions and 16 deletions
@@ -1,4 +1,10 @@
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import {
ApiExtraModels,
ApiOperation,
ApiResponse,
ApiTags,
getSchemaPath,
} from '@nestjs/swagger';
import {
Body,
Controller,
@@ -18,9 +24,11 @@ import { PermissionGuard } from '@/modules/Roles/Permission.guard';
import { AuthorizationGuard } from '@/modules/Roles/Authorization.guard';
import { AbilitySubject } from '@/modules/Roles/Roles.types';
import { CreditNoteAction } from '../CreditNotes/types/CreditNotes.types';
import { RefundCreditNoteResponseDto } from './dto/RefundCreditNoteResponse.dto';
@Controller('credit-notes')
@ApiTags('Credit Note Refunds')
@ApiExtraModels(RefundCreditNoteResponseDto)
@ApiCommonHeaders()
@UseGuards(AuthorizationGuard, PermissionGuard)
export class CreditNoteRefundsController {
@@ -31,12 +39,38 @@ export class CreditNoteRefundsController {
@Get(':creditNoteId/refunds')
@RequirePermission(CreditNoteAction.View, AbilitySubject.CreditNote)
@ApiOperation({ summary: 'Retrieve the credit note graph.' })
@ApiResponse({
status: 200,
description: 'Credit note refunds retrieved successfully.',
schema: {
type: 'array',
items: { $ref: getSchemaPath(RefundCreditNoteResponseDto) },
},
})
getCreditNoteRefunds(@Param('creditNoteId') creditNoteId: number) {
return this.creditNotesRefundsApplication.getCreditNoteRefunds(
creditNoteId,
);
}
@Get('refunds/:refundCreditId')
@RequirePermission(CreditNoteAction.View, AbilitySubject.CreditNote)
@ApiOperation({ summary: 'Retrieve a refund transaction for the given credit note.' })
@ApiResponse({
status: 200,
description: 'Refund credit note transaction retrieved successfully.',
schema: {
$ref: getSchemaPath(RefundCreditNoteResponseDto),
},
})
getRefundCreditNoteTransaction(
@Param('refundCreditId') refundCreditId: number,
) {
return this.creditNotesRefundsApplication.getRefundCreditNoteTransaction(
refundCreditId,
);
}
/**
* Create a refund credit note.
* @param {number} creditNoteId - The credit note ID.
@@ -7,6 +7,7 @@ import { CreditNotesRefundsApplication } from './CreditNotesRefundsApplication.s
import { CreditNoteRefundsController } from './CreditNoteRefunds.controller';
import { CreditNotesModule } from '../CreditNotes/CreditNotes.module';
import { GetCreditNoteRefundsService } from './queries/GetCreditNoteRefunds.service';
import { GetRefundCreditNoteTransaction } from './queries/GetRefundCreditNoteTransaction.service';
import { RefundCreditNoteGLEntries } from './commands/RefundCreditNoteGLEntries';
import { RefundCreditNoteGLEntriesSubscriber } from '../CreditNotes/subscribers/RefundCreditNoteGLEntriesSubscriber';
import { LedgerModule } from '../Ledger/Ledger.module';
@@ -21,6 +22,7 @@ import { AccountsModule } from '../Accounts/Accounts.module';
RefundSyncCreditNoteBalanceService,
CreditNotesRefundsApplication,
GetCreditNoteRefundsService,
GetRefundCreditNoteTransaction,
RefundCreditNoteGLEntries,
RefundCreditNoteGLEntriesSubscriber,
],
@@ -6,6 +6,7 @@ import { RefundCreditNoteService } from './commands/RefundCreditNote.service';
import { RefundSyncCreditNoteBalanceService } from './commands/RefundSyncCreditNoteBalance';
import { CreditNoteRefundDto } from './dto/CreditNoteRefund.dto';
import { GetCreditNoteRefundsService } from './queries/GetCreditNoteRefunds.service';
import { GetRefundCreditNoteTransaction } from './queries/GetRefundCreditNoteTransaction.service';
@Injectable()
export class CreditNotesRefundsApplication {
@@ -13,6 +14,7 @@ export class CreditNotesRefundsApplication {
private readonly createRefundCreditNoteService: CreateRefundCreditNoteService,
private readonly deleteRefundCreditNoteService: DeleteRefundCreditNoteService,
private readonly getCreditNoteRefundsService: GetCreditNoteRefundsService,
private readonly getRefundCreditNoteTransactionService: GetRefundCreditNoteTransaction,
private readonly refundCreditNoteService: RefundCreditNoteService,
private readonly refundSyncCreditNoteBalanceService: RefundSyncCreditNoteBalanceService,
) {}
@@ -26,6 +28,12 @@ export class CreditNotesRefundsApplication {
return this.getCreditNoteRefundsService.getCreditNoteRefunds(creditNoteId);
}
public getRefundCreditNoteTransaction(refundCreditId: number) {
return this.getRefundCreditNoteTransactionService.getRefundCreditTransaction(
refundCreditId,
);
}
/**
* Create a refund credit note.
* @param {number} creditNoteId - The credit note ID.
@@ -0,0 +1,46 @@
import { ApiProperty } from '@nestjs/swagger';
class RefundCreditNoteSummaryDto {
@ApiProperty({ example: 1 })
id: number;
@ApiProperty({ example: 'CN-0001' })
creditNoteNumber: string;
}
class RefundCreditAccountDto {
@ApiProperty({ example: 10 })
id: number;
@ApiProperty({ example: 'Cash on Hand' })
name: string;
}
export class RefundCreditNoteResponseDto {
@ApiProperty({ example: 100 })
id: number;
@ApiProperty({ example: '2024-01-15' })
date: string;
@ApiProperty({ example: '2024-01-15' })
formattedDate: string;
@ApiProperty({ example: 250 })
amount: number;
@ApiProperty({ example: '$250.00' })
formttedAmount: string;
@ApiProperty({ example: 'REF-001', required: false, nullable: true })
referenceNo?: string | null;
@ApiProperty({ example: 'Refund issued to customer', required: false, nullable: true })
description?: string | null;
@ApiProperty({ type: RefundCreditAccountDto })
fromAccount: RefundCreditAccountDto;
@ApiProperty({ type: RefundCreditNoteSummaryDto })
creditNote: RefundCreditNoteSummaryDto;
}
@@ -7,7 +7,13 @@ import {
Post,
UseGuards,
} from '@nestjs/common';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import {
ApiExtraModels,
ApiOperation,
ApiResponse,
ApiTags,
getSchemaPath,
} from '@nestjs/swagger';
import { GetCreditNoteAssociatedAppliedInvoices } from './queries/GetCreditNoteAssociatedAppliedInvoices.service';
import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders';
import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator';
@@ -19,9 +25,12 @@ import { GetCreditNoteAssociatedInvoicesToApply } from './queries/GetCreditNoteA
import { CreditNoteApplyToInvoices } from './commands/CreditNoteApplyToInvoices.service';
import { DeleteCreditNoteApplyToInvoices } from './commands/DeleteCreditNoteApplyToInvoices.service';
import { ApplyCreditNoteToInvoicesDto } from './dtos/ApplyCreditNoteToInvoices.dto';
import { AppliedCreditNoteInvoiceResponseDto } from './dtos/AppliedCreditNoteInvoiceResponse.dto';
import { CreditNoteInvoiceToApplyResponseDto } from './dtos/CreditNoteInvoiceToApplyResponse.dto';
@Controller('credit-notes')
@ApiTags('Credit Notes Apply Invoice')
@ApiExtraModels(AppliedCreditNoteInvoiceResponseDto, CreditNoteInvoiceToApplyResponseDto)
@ApiCommonHeaders()
@UseGuards(AuthorizationGuard, PermissionGuard)
export class CreditNotesApplyInvoiceController {
@@ -38,6 +47,10 @@ export class CreditNotesApplyInvoiceController {
@ApiResponse({
status: 200,
description: 'Credit note successfully applied to invoices',
schema: {
type: 'array',
items: { $ref: getSchemaPath(AppliedCreditNoteInvoiceResponseDto) },
},
})
@ApiResponse({ status: 404, description: 'Credit note not found' })
@ApiResponse({ status: 400, description: 'Invalid input data' })
@@ -53,6 +66,10 @@ export class CreditNotesApplyInvoiceController {
@ApiResponse({
status: 200,
description: 'Credit note associated invoices to apply',
schema: {
type: 'array',
items: { $ref: getSchemaPath(CreditNoteInvoiceToApplyResponseDto) },
},
})
@ApiResponse({ status: 404, description: 'Credit note not found' })
@ApiResponse({ status: 400, description: 'Invalid input data' })
@@ -0,0 +1,27 @@
import { ApiProperty } from '@nestjs/swagger';
export class AppliedCreditNoteInvoiceResponseDto {
@ApiProperty({ example: 1 })
id: number;
@ApiProperty({ example: 200 })
amount: number;
@ApiProperty({ example: '$200.00' })
formttedAmount: string;
@ApiProperty({ example: 'CN-0001' })
creditNoteNumber: string;
@ApiProperty({ example: '2024-01-10' })
creditNoteDate: string;
@ApiProperty({ example: '2024-01-10' })
formattedCreditNoteDate: string;
@ApiProperty({ example: 'INV-0001' })
invoiceNumber: string;
@ApiProperty({ example: 'REF-001', required: false, nullable: true })
invoiceReferenceNo?: string | null;
}
@@ -0,0 +1,45 @@
import { ApiProperty } from '@nestjs/swagger';
export class CreditNoteInvoiceToApplyResponseDto {
@ApiProperty({ example: 1 })
id: number;
@ApiProperty({ example: 'INV-0001' })
invoiceNo: string;
@ApiProperty({ example: 'REF-001', required: false, nullable: true })
referenceNo?: string | null;
@ApiProperty({ example: '2024-01-10' })
invoiceDate: string;
@ApiProperty({ example: '2024-01-20' })
dueDate: string;
@ApiProperty({ example: 'USD', required: false, nullable: true })
currencyCode?: string | null;
@ApiProperty({ example: 500 })
balance: number;
@ApiProperty({ example: 500 })
dueAmount: number;
@ApiProperty({ example: 0 })
paymentAmount: number;
@ApiProperty({ example: '2024-01-10' })
formattedInvoiceDate: string;
@ApiProperty({ example: '2024-01-20' })
formattedDueDate: string;
@ApiProperty({ example: '$500.00' })
formatted_amount: string;
@ApiProperty({ example: '$500.00' })
formattedDueAmount: string;
@ApiProperty({ example: '$0.00' })
formattedPaymentAmount: string;
}
@@ -20,6 +20,8 @@ import { InventoryAdjustmentsApplicationService } from './InventoryAdjustmentsAp
import { IInventoryAdjustmentsFilter } from './types/InventoryAdjustments.types';
import { InventoryAdjustment } from './models/InventoryAdjustment';
import { CreateQuickInventoryAdjustmentDto } from './dtos/CreateQuickInventoryAdjustment.dto';
import { InventoryAdjustmentsFilterDto } from './dtos/InventoryAdjustmentsFilter.dto';
import { InventoryAdjustmentsListResponseDto } from './dtos/InventoryAdjustmentsListResponse.dto';
import { InventoryAdjustmentResponseDto } from './dtos/InventoryAdjustmentResponse.dto';
import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders';
import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator';
@@ -31,6 +33,7 @@ import { InventoryAdjustmentAction } from './types/InventoryAdjustments.types';
@Controller('inventory-adjustments')
@ApiTags('Inventory Adjustments')
@ApiExtraModels(InventoryAdjustmentResponseDto)
@ApiExtraModels(InventoryAdjustmentsListResponseDto)
@ApiCommonHeaders()
@UseGuards(AuthorizationGuard, PermissionGuard)
export class InventoryAdjustmentsController {
@@ -75,15 +78,14 @@ export class InventoryAdjustmentsController {
status: 200,
description: 'The inventory adjustments have been successfully retrieved.',
schema: {
type: 'array',
items: { $ref: getSchemaPath(InventoryAdjustmentResponseDto) },
$ref: getSchemaPath(InventoryAdjustmentsListResponseDto),
},
})
public async getInventoryAdjustments(
@Query() filterDTO: IInventoryAdjustmentsFilter,
@Query() filterDTO: InventoryAdjustmentsFilterDto,
) {
return this.inventoryAdjustmentsApplicationService.getInventoryAdjustments(
filterDTO,
filterDTO as IInventoryAdjustmentsFilter,
);
}
@@ -0,0 +1,9 @@
import { ApiPropertyOptional } from '@nestjs/swagger';
export class InventoryAdjustmentsFilterDto {
@ApiPropertyOptional({ example: 1 })
page?: number;
@ApiPropertyOptional({ example: 12 })
pageSize?: number;
}
@@ -0,0 +1,21 @@
import { ApiProperty } from '@nestjs/swagger';
import { InventoryAdjustmentResponseDto } from './InventoryAdjustmentResponse.dto';
class InventoryAdjustmentsPaginationDto {
@ApiProperty({ example: 1 })
page: number;
@ApiProperty({ example: 12 })
pageSize: number;
@ApiProperty({ example: 42 })
total: number;
}
export class InventoryAdjustmentsListResponseDto {
@ApiProperty({ type: [InventoryAdjustmentResponseDto] })
data: InventoryAdjustmentResponseDto[];
@ApiProperty({ type: InventoryAdjustmentsPaginationDto })
pagination: InventoryAdjustmentsPaginationDto;
}
@@ -1,13 +1,22 @@
import { Controller, Get } from '@nestjs/common';
import { GetDateFormatsService } from './queries/GetDateFormats.service';
import { ApiTags } from '@nestjs/swagger';
import { ApiExtraModels, ApiResponse, ApiTags, getSchemaPath } from '@nestjs/swagger';
import { DateFormatResponseDto } from './dtos/DateFormatResponse.dto';
@Controller('/')
@ApiTags('misc')
@ApiExtraModels(DateFormatResponseDto)
export class MiscellaneousController {
constructor(private readonly getDateFormatsSevice: GetDateFormatsService) {}
@Get('/date-formats')
@ApiResponse({
status: 200,
schema: {
type: 'array',
items: { $ref: getSchemaPath(DateFormatResponseDto) },
},
})
getDateFormats() {
return this.getDateFormatsSevice.getDateFormats();
}
@@ -0,0 +1,9 @@
import { ApiProperty } from '@nestjs/swagger';
export class DateFormatResponseDto {
@ApiProperty({ example: '03/09/2026 [MM/DD/YYYY]' })
label: string;
@ApiProperty({ example: 'MM/DD/YYYY' })
key: string;
}
@@ -36,6 +36,7 @@ import {
OrganizationBuiltResponseExample,
} from './Organization.swagger';
import { GetCurrentOrganizationResponseDto } from './dtos/GetCurrentOrganizationResponse.dto';
import { OrganizationBuildJobResponseDto } from './dtos/OrganizationBuildJobResponse.dto';
import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders';
@ApiTags('Organization')
@@ -44,6 +45,7 @@ import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders';
@IgnoreTenantSeededRoute()
@IgnoreTenantModelsInitialize()
@ApiExtraModels(GetCurrentOrganizationResponseDto)
@ApiExtraModels(OrganizationBuildJobResponseDto)
@ApiCommonHeaders()
export class OrganizationController {
constructor(
@@ -88,6 +90,13 @@ export class OrganizationController {
})
@HttpCode(200)
@ApiOperation({ summary: 'Gets the organization build job details' })
@ApiResponse({
status: 200,
description: 'Returns the organization build job details',
schema: {
$ref: getSchemaPath(OrganizationBuildJobResponseDto),
},
})
async buildJob(@Param('buildJobId') buildJobId: string) {
return this.getBuildOrganizationJobService.getJobDetails(buildJobId);
}
@@ -0,0 +1,24 @@
import { ApiProperty } from '@nestjs/swagger';
export class OrganizationBuildJobResponseDto {
@ApiProperty({ example: '123' })
id: string;
@ApiProperty({ example: 'active' })
state: string;
@ApiProperty({ example: 50 })
progress: number | Record<string, unknown>;
@ApiProperty({ example: false })
isCompleted: boolean;
@ApiProperty({ example: true })
isRunning: boolean;
@ApiProperty({ example: false })
isWaiting: boolean;
@ApiProperty({ example: false })
isFailed: boolean;
}