diff --git a/packages/server/src/modules/Accounts/Accounts.controller.ts b/packages/server/src/modules/Accounts/Accounts.controller.ts index 7a9f26163..656d2d80a 100644 --- a/packages/server/src/modules/Accounts/Accounts.controller.ts +++ b/packages/server/src/modules/Accounts/Accounts.controller.ts @@ -41,6 +41,39 @@ import { export class AccountsController { constructor(private readonly accountsApplication: AccountsApplication) { } + @Post('validate-bulk-delete') + @ApiOperation({ + summary: + 'Validates which accounts can be deleted and returns counts of deletable and non-deletable accounts.', + }) + @ApiResponse({ + status: 200, + description: + 'Validation completed. Returns counts and IDs of deletable and non-deletable accounts.', + schema: { + $ref: getSchemaPath(ValidateBulkDeleteResponseDto), + }, + }) + async validateBulkDeleteAccounts( + @Body() bulkDeleteDto: BulkDeleteDto, + ): Promise { + return this.accountsApplication.validateBulkDeleteAccounts( + bulkDeleteDto.ids, + ); + } + + @Post('bulk-delete') + @ApiOperation({ summary: 'Deletes multiple accounts in bulk.' }) + @ApiResponse({ + status: 200, + description: 'The accounts have been successfully deleted.', + }) + async bulkDeleteAccounts( + @Body() bulkDeleteDto: BulkDeleteDto, + ): Promise { + return this.accountsApplication.bulkDeleteAccounts(bulkDeleteDto.ids); + } + @Post() @ApiOperation({ summary: 'Create an account' }) @ApiResponse({ @@ -88,37 +121,6 @@ export class AccountsController { return this.accountsApplication.deleteAccount(id); } - @Post('validate-bulk-delete') - @ApiOperation({ - summary: - 'Validates which accounts can be deleted and returns counts of deletable and non-deletable accounts.', - }) - @ApiResponse({ - status: 200, - description: - 'Validation completed. Returns counts and IDs of deletable and non-deletable accounts.', - schema: { - $ref: getSchemaPath(ValidateBulkDeleteResponseDto), - }, - }) - async validateBulkDeleteAccounts( - @Body() bulkDeleteDto: BulkDeleteDto, - ): Promise { - return this.accountsApplication.validateBulkDeleteAccounts( - bulkDeleteDto.ids, - ); - } - - @Post('bulk-delete') - @ApiOperation({ summary: 'Deletes multiple accounts in bulk.' }) - @ApiResponse({ - status: 200, - description: 'The accounts have been successfully deleted.', - }) - async bulkDeleteAccounts(@Body() bulkDeleteDto: BulkDeleteDto): Promise { - return this.accountsApplication.bulkDeleteAccounts(bulkDeleteDto.ids); - } - @Post(':id/activate') @ApiOperation({ summary: 'Activate the given account.' }) @ApiResponse({ diff --git a/packages/server/src/modules/Bills/Bills.application.ts b/packages/server/src/modules/Bills/Bills.application.ts index 5c02bbc39..a33f0adfd 100644 --- a/packages/server/src/modules/Bills/Bills.application.ts +++ b/packages/server/src/modules/Bills/Bills.application.ts @@ -9,6 +9,8 @@ import { Injectable } from '@nestjs/common'; import { GetBillsService } from './queries/GetBills.service'; import { CreateBillDto, EditBillDto } from './dtos/Bill.dto'; import { GetBillPaymentTransactionsService } from './queries/GetBillPayments'; +import { BulkDeleteBillsService } from './BulkDeleteBills.service'; +import { ValidateBulkDeleteBillsService } from './ValidateBulkDeleteBills.service'; // import { GetBillPayments } from './queries/GetBillPayments'; // import { GetBills } from './queries/GetBills'; @@ -23,7 +25,9 @@ export class BillsApplication { private openBillService: OpenBillService, private getBillsService: GetBillsService, private getBillPaymentTransactionsService: GetBillPaymentTransactionsService, - ) {} + private bulkDeleteBillsService: BulkDeleteBillsService, + private validateBulkDeleteBillsService: ValidateBulkDeleteBillsService, + ) { } /** * Creates a new bill with associated GL entries. @@ -53,6 +57,22 @@ export class BillsApplication { return this.deleteBillService.deleteBill(billId); } + /** + * Deletes multiple bills. + * @param {number[]} billIds + */ + public bulkDeleteBills(billIds: number[]) { + return this.bulkDeleteBillsService.bulkDeleteBills(billIds); + } + + /** + * Validates which bills can be deleted. + * @param {number[]} billIds + */ + public validateBulkDeleteBills(billIds: number[]) { + return this.validateBulkDeleteBillsService.validateBulkDeleteBills(billIds); + } + /** * Retrieve bills data table list. * @param {IBillsFilter} billsFilter - diff --git a/packages/server/src/modules/Bills/Bills.controller.ts b/packages/server/src/modules/Bills/Bills.controller.ts index c77639715..3bb401f35 100644 --- a/packages/server/src/modules/Bills/Bills.controller.ts +++ b/packages/server/src/modules/Bills/Bills.controller.ts @@ -22,14 +22,47 @@ import { CreateBillDto, EditBillDto } from './dtos/Bill.dto'; import { BillResponseDto } from './dtos/BillResponse.dto'; import { PaginatedResponseDto } from '@/common/dtos/PaginatedResults.dto'; import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; +import { + BulkDeleteDto, + ValidateBulkDeleteResponseDto, +} from '@/common/dtos/BulkDelete.dto'; @Controller('bills') @ApiTags('Bills') @ApiExtraModels(BillResponseDto) @ApiExtraModels(PaginatedResponseDto) @ApiCommonHeaders() +@ApiExtraModels(ValidateBulkDeleteResponseDto) export class BillsController { - constructor(private billsApplication: BillsApplication) {} + constructor(private billsApplication: BillsApplication) { } + + @Post('validate-bulk-delete') + @ApiOperation({ + summary: 'Validate which bills can be deleted and return the results.', + }) + @ApiResponse({ + status: 200, + description: + 'Validation completed with counts and IDs of deletable and non-deletable bills.', + schema: { + $ref: getSchemaPath(ValidateBulkDeleteResponseDto), + }, + }) + validateBulkDeleteBills( + @Body() bulkDeleteDto: BulkDeleteDto, + ): Promise { + return this.billsApplication.validateBulkDeleteBills(bulkDeleteDto.ids); + } + + @Post('bulk-delete') + @ApiOperation({ summary: 'Deletes multiple bills.' }) + @ApiResponse({ + status: 200, + description: 'Bills deleted successfully', + }) + bulkDeleteBills(@Body() bulkDeleteDto: BulkDeleteDto): Promise { + return this.billsApplication.bulkDeleteBills(bulkDeleteDto.ids); + } @Post() @ApiOperation({ summary: 'Create a new bill.' }) diff --git a/packages/server/src/modules/Bills/Bills.module.ts b/packages/server/src/modules/Bills/Bills.module.ts index a9599cea9..7b768f124 100644 --- a/packages/server/src/modules/Bills/Bills.module.ts +++ b/packages/server/src/modules/Bills/Bills.module.ts @@ -29,6 +29,8 @@ import { InventoryCostModule } from '../InventoryCost/InventoryCost.module'; import { BillsExportable } from './commands/BillsExportable'; import { BillsImportable } from './commands/BillsImportable'; import { GetBillPaymentTransactionsService } from './queries/GetBillPayments'; +import { BulkDeleteBillsService } from './BulkDeleteBills.service'; +import { ValidateBulkDeleteBillsService } from './ValidateBulkDeleteBills.service'; @Module({ imports: [ @@ -63,8 +65,10 @@ import { GetBillPaymentTransactionsService } from './queries/GetBillPayments'; BillsExportable, BillsImportable, GetBillPaymentTransactionsService, + BulkDeleteBillsService, + ValidateBulkDeleteBillsService, ], controllers: [BillsController], exports: [BillsExportable, BillsImportable], }) -export class BillsModule {} +export class BillsModule { } diff --git a/packages/server/src/modules/Expenses/Expenses.controller.ts b/packages/server/src/modules/Expenses/Expenses.controller.ts index 2dfb05409..8ee22ffb3 100644 --- a/packages/server/src/modules/Expenses/Expenses.controller.ts +++ b/packages/server/src/modules/Expenses/Expenses.controller.ts @@ -21,13 +21,51 @@ import { CreateExpenseDto, EditExpenseDto } from './dtos/Expense.dto'; import { PaginatedResponseDto } from '@/common/dtos/PaginatedResults.dto'; import { ExpenseResponseDto } from './dtos/ExpenseResponse.dto'; import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; +import { + BulkDeleteDto, + ValidateBulkDeleteResponseDto, +} from '@/common/dtos/BulkDelete.dto'; @Controller('expenses') @ApiTags('Expenses') -@ApiExtraModels(PaginatedResponseDto, ExpenseResponseDto) +@ApiExtraModels( + PaginatedResponseDto, + ExpenseResponseDto, + ValidateBulkDeleteResponseDto, +) @ApiCommonHeaders() export class ExpensesController { - constructor(private readonly expensesApplication: ExpensesApplication) {} + constructor(private readonly expensesApplication: ExpensesApplication) { } + + @Post('validate-bulk-delete') + @ApiOperation({ + summary: 'Validate which expenses can be deleted and return the results.', + }) + @ApiResponse({ + status: 200, + description: + 'Validation completed with counts and IDs of deletable and non-deletable expenses.', + schema: { + $ref: getSchemaPath(ValidateBulkDeleteResponseDto), + }, + }) + public validateBulkDeleteExpenses( + @Body() bulkDeleteDto: BulkDeleteDto, + ): Promise { + return this.expensesApplication.validateBulkDeleteExpenses( + bulkDeleteDto.ids, + ); + } + + @Post('bulk-delete') + @ApiOperation({ summary: 'Deletes multiple expenses.' }) + @ApiResponse({ + status: 200, + description: 'Expenses deleted successfully', + }) + public bulkDeleteExpenses(@Body() bulkDeleteDto: BulkDeleteDto) { + return this.expensesApplication.bulkDeleteExpenses(bulkDeleteDto.ids); + } /** * Create a new expense transaction. diff --git a/packages/server/src/modules/Expenses/Expenses.module.ts b/packages/server/src/modules/Expenses/Expenses.module.ts index 9a36478ab..4041acb06 100644 --- a/packages/server/src/modules/Expenses/Expenses.module.ts +++ b/packages/server/src/modules/Expenses/Expenses.module.ts @@ -19,6 +19,8 @@ import { GetExpensesService } from './queries/GetExpenses.service'; import { DynamicListModule } from '../DynamicListing/DynamicList.module'; import { ExpensesExportable } from './ExpensesExportable'; import { ExpensesImportable } from './ExpensesImportable'; +import { BulkDeleteExpensesService } from './BulkDeleteExpenses.service'; +import { ValidateBulkDeleteExpensesService } from './ValidateBulkDeleteExpenses.service'; @Module({ imports: [LedgerModule, BranchesModule, DynamicListModule], @@ -41,6 +43,8 @@ import { ExpensesImportable } from './ExpensesImportable'; GetExpensesService, ExpensesExportable, ExpensesImportable, + BulkDeleteExpensesService, + ValidateBulkDeleteExpensesService, ], }) export class ExpensesModule {} diff --git a/packages/server/src/modules/Expenses/ExpensesApplication.service.ts b/packages/server/src/modules/Expenses/ExpensesApplication.service.ts index 18e611655..a0b08ce45 100644 --- a/packages/server/src/modules/Expenses/ExpensesApplication.service.ts +++ b/packages/server/src/modules/Expenses/ExpensesApplication.service.ts @@ -7,6 +7,8 @@ import { GetExpenseService } from './queries/GetExpense.service'; import { IExpensesFilter } from './interfaces/Expenses.interface'; import { GetExpensesService } from './queries/GetExpenses.service'; import { CreateExpenseDto, EditExpenseDto } from './dtos/Expense.dto'; +import { BulkDeleteExpensesService } from './BulkDeleteExpenses.service'; +import { ValidateBulkDeleteExpensesService } from './ValidateBulkDeleteExpenses.service'; @Injectable() export class ExpensesApplication { @@ -17,6 +19,8 @@ export class ExpensesApplication { private readonly publishExpenseService: PublishExpense, private readonly getExpenseService: GetExpenseService, private readonly getExpensesService: GetExpensesService, + private readonly bulkDeleteExpensesService: BulkDeleteExpensesService, + private readonly validateBulkDeleteExpensesService: ValidateBulkDeleteExpensesService, ) {} /** @@ -47,6 +51,24 @@ export class ExpensesApplication { return this.deleteExpenseService.deleteExpense(expenseId); } + /** + * Deletes expenses in bulk. + * @param {number[]} expenseIds - Expense ids. + */ + public bulkDeleteExpenses(expenseIds: number[]) { + return this.bulkDeleteExpensesService.bulkDeleteExpenses(expenseIds); + } + + /** + * Validates which expenses can be deleted. + * @param {number[]} expenseIds - Expense ids. + */ + public validateBulkDeleteExpenses(expenseIds: number[]) { + return this.validateBulkDeleteExpensesService.validateBulkDeleteExpenses( + expenseIds, + ); + } + /** * Publishes the given expense. * @param {number} expenseId - Expense id. diff --git a/packages/server/src/modules/ManualJournals/ManualJournals.controller.ts b/packages/server/src/modules/ManualJournals/ManualJournals.controller.ts index 1d813c346..b2baf7ee2 100644 --- a/packages/server/src/modules/ManualJournals/ManualJournals.controller.ts +++ b/packages/server/src/modules/ManualJournals/ManualJournals.controller.ts @@ -25,13 +25,53 @@ import { import { IManualJournalsFilter } from './types/ManualJournals.types'; import { ManualJournalResponseDto } from './dtos/ManualJournalResponse.dto'; import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; +import { + BulkDeleteDto, + ValidateBulkDeleteResponseDto, +} from '@/common/dtos/BulkDelete.dto'; @Controller('manual-journals') @ApiTags('Manual Journals') @ApiExtraModels(ManualJournalResponseDto) +@ApiExtraModels(ValidateBulkDeleteResponseDto) @ApiCommonHeaders() export class ManualJournalsController { - constructor(private manualJournalsApplication: ManualJournalsApplication) {} + constructor(private manualJournalsApplication: ManualJournalsApplication) { } + + @Post('validate-bulk-delete') + @ApiOperation({ + summary: + 'Validate which manual journals can be deleted and return the results.', + }) + @ApiResponse({ + status: 200, + description: + 'Validation completed with counts and IDs of deletable and non-deletable manual journals.', + schema: { + $ref: getSchemaPath(ValidateBulkDeleteResponseDto), + }, + }) + public validateBulkDeleteManualJournals( + @Body() bulkDeleteDto: BulkDeleteDto, + ): Promise { + return this.manualJournalsApplication.validateBulkDeleteManualJournals( + bulkDeleteDto.ids, + ); + } + + @Post('bulk-delete') + @ApiOperation({ summary: 'Deletes multiple manual journals.' }) + @ApiResponse({ + status: 200, + description: 'Manual journals deleted successfully', + }) + public bulkDeleteManualJournals( + @Body() bulkDeleteDto: BulkDeleteDto, + ): Promise { + return this.manualJournalsApplication.bulkDeleteManualJournals( + bulkDeleteDto.ids, + ); + } @Post() @ApiOperation({ summary: 'Create a new manual journal.' }) diff --git a/packages/server/src/modules/ManualJournals/ManualJournals.module.ts b/packages/server/src/modules/ManualJournals/ManualJournals.module.ts index be1dabfb8..cbe5aae89 100644 --- a/packages/server/src/modules/ManualJournals/ManualJournals.module.ts +++ b/packages/server/src/modules/ManualJournals/ManualJournals.module.ts @@ -19,6 +19,8 @@ import { ManualJournalsExportable } from './commands/ManualJournalExportable'; import { ManualJournalImportable } from './commands/ManualJournalsImport'; import { GetManualJournals } from './queries/GetManualJournals.service'; import { DynamicListModule } from '../DynamicListing/DynamicList.module'; +import { BulkDeleteManualJournalsService } from './BulkDeleteManualJournals.service'; +import { ValidateBulkDeleteManualJournalsService } from './ValidateBulkDeleteManualJournals.service'; @Module({ imports: [BranchesModule, LedgerModule, DynamicListModule], @@ -41,6 +43,8 @@ import { DynamicListModule } from '../DynamicListing/DynamicList.module'; ManualJournalWriteGLSubscriber, ManualJournalsExportable, ManualJournalImportable, + BulkDeleteManualJournalsService, + ValidateBulkDeleteManualJournalsService, ], exports: [ManualJournalsExportable, ManualJournalImportable], }) diff --git a/packages/server/src/modules/ManualJournals/ManualJournalsApplication.service.ts b/packages/server/src/modules/ManualJournals/ManualJournalsApplication.service.ts index 9fdba3557..5f956af79 100644 --- a/packages/server/src/modules/ManualJournals/ManualJournalsApplication.service.ts +++ b/packages/server/src/modules/ManualJournals/ManualJournalsApplication.service.ts @@ -10,6 +10,8 @@ import { EditManualJournalDto, } from './dtos/ManualJournal.dto'; import { GetManualJournals } from './queries/GetManualJournals.service'; +import { BulkDeleteManualJournalsService } from './BulkDeleteManualJournals.service'; +import { ValidateBulkDeleteManualJournalsService } from './ValidateBulkDeleteManualJournals.service'; // import { GetManualJournals } from './queries/GetManualJournals'; @Injectable() @@ -21,6 +23,8 @@ export class ManualJournalsApplication { private publishManualJournalService: PublishManualJournal, private getManualJournalService: GetManualJournal, private getManualJournalsService: GetManualJournals, + private bulkDeleteManualJournalsService: BulkDeleteManualJournalsService, + private validateBulkDeleteManualJournalsService: ValidateBulkDeleteManualJournalsService, ) {} /** @@ -57,6 +61,26 @@ export class ManualJournalsApplication { return this.deleteManualJournalService.deleteManualJournal(manualJournalId); }; + /** + * Bulk deletes manual journals. + * @param {number[]} manualJournalIds + */ + public bulkDeleteManualJournals = (manualJournalIds: number[]) => { + return this.bulkDeleteManualJournalsService.bulkDeleteManualJournals( + manualJournalIds, + ); + }; + + /** + * Validates which manual journals can be deleted. + * @param {number[]} manualJournalIds + */ + public validateBulkDeleteManualJournals = (manualJournalIds: number[]) => { + return this.validateBulkDeleteManualJournalsService.validateBulkDeleteManualJournals( + manualJournalIds, + ); + }; + /** * Publish the given manual journal. * @param {number} manualJournalId - Manual journal id. diff --git a/packages/server/src/modules/PaymentReceived/PaymentReceived.application.ts b/packages/server/src/modules/PaymentReceived/PaymentReceived.application.ts index 2a51c5155..61ea93f12 100644 --- a/packages/server/src/modules/PaymentReceived/PaymentReceived.application.ts +++ b/packages/server/src/modules/PaymentReceived/PaymentReceived.application.ts @@ -18,6 +18,8 @@ import { } from './dtos/PaymentReceived.dto'; import { PaymentsReceivedPagesService } from './queries/PaymentsReceivedPages.service'; import { GetPaymentReceivedMailState } from './queries/GetPaymentReceivedMailState.service'; +import { BulkDeletePaymentReceivedService } from './BulkDeletePaymentReceived.service'; +import { ValidateBulkDeletePaymentReceivedService } from './ValidateBulkDeletePaymentReceived.service'; @Injectable() export class PaymentReceivesApplication { @@ -33,7 +35,9 @@ export class PaymentReceivesApplication { private getPaymentReceivePdfService: GetPaymentReceivedPdfService, private getPaymentReceivedStateService: GetPaymentReceivedStateService, private paymentsReceivedPagesService: PaymentsReceivedPagesService, - ) {} + private bulkDeletePaymentReceivedService: BulkDeletePaymentReceivedService, + private validateBulkDeletePaymentReceivedService: ValidateBulkDeletePaymentReceivedService, + ) { } /** * Creates a new payment receive. @@ -73,6 +77,25 @@ export class PaymentReceivesApplication { ); } + /** + * Deletes multiple payment receives. + * @param {number[]} paymentReceiveIds + */ + public bulkDeletePaymentReceives(paymentReceiveIds: number[]) { + return this.bulkDeletePaymentReceivedService.bulkDeletePaymentReceived( + paymentReceiveIds, + ); + } + + /** + * Validates which payment receives can be deleted. + * @param {number[]} paymentReceiveIds + */ + public validateBulkDeletePaymentReceives(paymentReceiveIds: number[]) { + return this.validateBulkDeletePaymentReceivedService + .validateBulkDeletePaymentReceived(paymentReceiveIds); + } + /** * Retrieve payment receives paginated and filterable. * @param {number} tenantId diff --git a/packages/server/src/modules/PaymentReceived/PaymentsReceived.controller.ts b/packages/server/src/modules/PaymentReceived/PaymentsReceived.controller.ts index abc5577d0..31fb9c87b 100644 --- a/packages/server/src/modules/PaymentReceived/PaymentsReceived.controller.ts +++ b/packages/server/src/modules/PaymentReceived/PaymentsReceived.controller.ts @@ -32,15 +32,20 @@ import { PaymentReceivedResponseDto } from './dtos/PaymentReceivedResponse.dto'; import { PaginatedResponseDto } from '@/common/dtos/PaginatedResults.dto'; import { PaymentReceivedStateResponseDto } from './dtos/PaymentReceivedStateResponse.dto'; import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; +import { + BulkDeleteDto, + ValidateBulkDeleteResponseDto, +} from '@/common/dtos/BulkDelete.dto'; @Controller('payments-received') @ApiTags('Payments Received') @ApiExtraModels(PaymentReceivedResponseDto) @ApiExtraModels(PaginatedResponseDto) @ApiExtraModels(PaymentReceivedStateResponseDto) +@ApiExtraModels(ValidateBulkDeleteResponseDto) @ApiCommonHeaders() export class PaymentReceivesController { - constructor(private paymentReceivesApplication: PaymentReceivesApplication) {} + constructor(private paymentReceivesApplication: PaymentReceivesApplication) { } @Post(':id/mail') @HttpCode(200) @@ -143,6 +148,39 @@ export class PaymentReceivesController { return this.paymentReceivesApplication.getPaymentsReceived(filterDTO); } + @Post('validate-bulk-delete') + @ApiOperation({ + summary: + 'Validates which payments received can be deleted and returns the results.', + }) + @ApiResponse({ + status: 200, + description: + 'Validation completed with counts and IDs of deletable and non-deletable payments received.', + schema: { + $ref: getSchemaPath(ValidateBulkDeleteResponseDto), + }, + }) + public validateBulkDeletePaymentsReceived( + @Body() bulkDeleteDto: BulkDeleteDto, + ): Promise { + return this.paymentReceivesApplication.validateBulkDeletePaymentReceives( + bulkDeleteDto.ids, + ); + } + + @Post('bulk-delete') + @ApiOperation({ summary: 'Deletes multiple payments received.' }) + @ApiResponse({ + status: 200, + description: 'Payments received deleted successfully.', + }) + public bulkDeletePaymentsReceived(@Body() bulkDeleteDto: BulkDeleteDto) { + return this.paymentReceivesApplication.bulkDeletePaymentReceives( + bulkDeleteDto.ids, + ); + } + @Get('state') @ApiOperation({ summary: 'Retrieves the payment received state.' }) @ApiResponse({ diff --git a/packages/server/src/modules/PaymentReceived/PaymentsReceived.module.ts b/packages/server/src/modules/PaymentReceived/PaymentsReceived.module.ts index 8d062a461..ed7d034b3 100644 --- a/packages/server/src/modules/PaymentReceived/PaymentsReceived.module.ts +++ b/packages/server/src/modules/PaymentReceived/PaymentsReceived.module.ts @@ -39,6 +39,8 @@ import { PaymentsReceivedImportable } from './commands/PaymentsReceivedImportabl import { PaymentsReceivedPagesService } from './queries/PaymentsReceivedPages.service'; import { GetPaymentReceivedMailTemplate } from './queries/GetPaymentReceivedMailTemplate.service'; import { GetPaymentReceivedMailState } from './queries/GetPaymentReceivedMailState.service'; +import { BulkDeletePaymentReceivedService } from './BulkDeletePaymentReceived.service'; +import { ValidateBulkDeletePaymentReceivedService } from './ValidateBulkDeletePaymentReceived.service'; @Module({ controllers: [PaymentReceivesController], @@ -68,7 +70,9 @@ import { GetPaymentReceivedMailState } from './queries/GetPaymentReceivedMailSta PaymentsReceivedImportable, PaymentsReceivedPagesService, GetPaymentReceivedMailTemplate, - GetPaymentReceivedMailState + GetPaymentReceivedMailState, + BulkDeletePaymentReceivedService, + ValidateBulkDeletePaymentReceivedService, ], exports: [ PaymentReceivesApplication, @@ -76,7 +80,7 @@ import { GetPaymentReceivedMailState } from './queries/GetPaymentReceivedMailSta PaymentReceivedGLEntries, PaymentsReceivedExportable, PaymentsReceivedImportable, - PaymentReceivedValidators + PaymentReceivedValidators, ], imports: [ ChromiumlyTenancyModule, diff --git a/packages/server/src/modules/SaleEstimates/SaleEstimates.application.ts b/packages/server/src/modules/SaleEstimates/SaleEstimates.application.ts index a8424755a..818e53e3b 100644 --- a/packages/server/src/modules/SaleEstimates/SaleEstimates.application.ts +++ b/packages/server/src/modules/SaleEstimates/SaleEstimates.application.ts @@ -19,6 +19,8 @@ import { EditSaleEstimateDto, } from './dtos/SaleEstimate.dto'; import { GetSaleEstimateMailStateService } from './queries/GetSaleEstimateMailState.service'; +import { BulkDeleteSaleEstimatesService } from './BulkDeleteSaleEstimates.service'; +import { ValidateBulkDeleteSaleEstimatesService } from './ValidateBulkDeleteSaleEstimates.service'; @Injectable() export class SaleEstimatesApplication { @@ -35,6 +37,8 @@ export class SaleEstimatesApplication { private readonly getSaleEstimateStateService: GetSaleEstimateState, private readonly saleEstimatesPdfService: GetSaleEstimatePdf, private readonly getSaleEstimateMailStateService: GetSaleEstimateMailStateService, + private readonly bulkDeleteSaleEstimatesService: BulkDeleteSaleEstimatesService, + private readonly validateBulkDeleteSaleEstimatesService: ValidateBulkDeleteSaleEstimatesService, ) {} /** @@ -68,6 +72,27 @@ export class SaleEstimatesApplication { return this.deleteSaleEstimateService.deleteEstimate(estimateId); } + /** + * Deletes multiple sale estimates. + * @param {number[]} saleEstimateIds + * @return {Promise} + */ + public bulkDeleteSaleEstimates(saleEstimateIds: number[]) { + return this.bulkDeleteSaleEstimatesService.bulkDeleteSaleEstimates( + saleEstimateIds, + ); + } + + /** + * Validates which sale estimates can be deleted. + * @param {number[]} saleEstimateIds + */ + public validateBulkDeleteSaleEstimates(saleEstimateIds: number[]) { + return this.validateBulkDeleteSaleEstimatesService.validateBulkDeleteSaleEstimates( + saleEstimateIds, + ); + } + /** * Retrieves the given sale estimate. * @param {number} estimateId - Sale estimate ID. diff --git a/packages/server/src/modules/SaleEstimates/SaleEstimates.controller.ts b/packages/server/src/modules/SaleEstimates/SaleEstimates.controller.ts index 449dbfce2..c1d3ac74e 100644 --- a/packages/server/src/modules/SaleEstimates/SaleEstimates.controller.ts +++ b/packages/server/src/modules/SaleEstimates/SaleEstimates.controller.ts @@ -36,6 +36,10 @@ import { SaleEstimateResponseDto } from './dtos/SaleEstimateResponse.dto'; import { PaginatedResponseDto } from '@/common/dtos/PaginatedResults.dto'; import { SaleEstiamteStateResponseDto } from './dtos/SaleEstimateStateResponse.dto'; import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; +import { + BulkDeleteDto, + ValidateBulkDeleteResponseDto, +} from '@/common/dtos/BulkDelete.dto'; @Controller('sale-estimates') @ApiTags('Sale Estimates') @@ -43,13 +47,49 @@ import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; @ApiExtraModels(PaginatedResponseDto) @ApiExtraModels(SaleEstiamteStateResponseDto) @ApiCommonHeaders() +@ApiExtraModels(ValidateBulkDeleteResponseDto) export class SaleEstimatesController { + @Post('validate-bulk-delete') + @ApiOperation({ + summary: + 'Validates which sale estimates can be deleted and returns the results.', + }) + @ApiResponse({ + status: 200, + description: + 'Validation completed with counts and IDs of deletable and non-deletable sale estimates.', + schema: { + $ref: getSchemaPath(ValidateBulkDeleteResponseDto), + }, + }) + public validateBulkDeleteSaleEstimates( + @Body() bulkDeleteDto: BulkDeleteDto, + ): Promise { + return this.saleEstimatesApplication.validateBulkDeleteSaleEstimates( + bulkDeleteDto.ids, + ); + } + + @Post('bulk-delete') + @ApiOperation({ summary: 'Deletes multiple sale estimates.' }) + @ApiResponse({ + status: 200, + description: 'Sale estimates deleted successfully', + }) + public bulkDeleteSaleEstimates( + @Body() bulkDeleteDto: BulkDeleteDto, + ): Promise { + return this.saleEstimatesApplication.bulkDeleteSaleEstimates( + bulkDeleteDto.ids, + ); + } + /** * @param {SaleEstimatesApplication} saleEstimatesApplication - Sale estimates application. */ constructor( private readonly saleEstimatesApplication: SaleEstimatesApplication, - ) {} + ) { } @Post() @ApiOperation({ summary: 'Create a new sale estimate.' }) diff --git a/packages/server/src/modules/SaleEstimates/SaleEstimates.module.ts b/packages/server/src/modules/SaleEstimates/SaleEstimates.module.ts index d4efa4564..a19ea923e 100644 --- a/packages/server/src/modules/SaleEstimates/SaleEstimates.module.ts +++ b/packages/server/src/modules/SaleEstimates/SaleEstimates.module.ts @@ -40,6 +40,8 @@ import { SaleEstimatesImportable } from './SaleEstimatesImportable'; import { GetSaleEstimateMailStateService } from './queries/GetSaleEstimateMailState.service'; import { GetSaleEstimateMailTemplateService } from './queries/GetSaleEstimateMailTemplate.service'; import { SaleEstimateAutoIncrementSubscriber } from './subscribers/SaleEstimateAutoIncrementSubscriber'; +import { BulkDeleteSaleEstimatesService } from './BulkDeleteSaleEstimates.service'; +import { ValidateBulkDeleteSaleEstimatesService } from './ValidateBulkDeleteSaleEstimates.service'; @Module({ imports: [ @@ -85,6 +87,8 @@ import { SaleEstimateAutoIncrementSubscriber } from './subscribers/SaleEstimateA GetSaleEstimateMailStateService, GetSaleEstimateMailTemplateService, SaleEstimateAutoIncrementSubscriber, + BulkDeleteSaleEstimatesService, + ValidateBulkDeleteSaleEstimatesService, ], exports: [ SaleEstimatesExportable, diff --git a/packages/server/src/modules/SaleInvoices/SaleInvoices.application.ts b/packages/server/src/modules/SaleInvoices/SaleInvoices.application.ts index 8c4911c10..eee2da24f 100644 --- a/packages/server/src/modules/SaleInvoices/SaleInvoices.application.ts +++ b/packages/server/src/modules/SaleInvoices/SaleInvoices.application.ts @@ -23,6 +23,8 @@ import { EditSaleInvoiceDto, } from './dtos/SaleInvoice.dto'; import { GenerateShareLink } from './commands/GenerateInvoicePaymentLink.service'; +import { BulkDeleteSaleInvoicesService } from './BulkDeleteSaleInvoices.service'; +import { ValidateBulkDeleteSaleInvoicesService } from './ValidateBulkDeleteSaleInvoices.service'; @Injectable() export class SaleInvoiceApplication { @@ -41,6 +43,8 @@ export class SaleInvoiceApplication { private sendSaleInvoiceMailService: SendSaleInvoiceMail, private getSaleInvoiceMailStateService: GetSaleInvoiceMailState, private generateShareLinkService: GenerateShareLink, + private bulkDeleteSaleInvoicesService: BulkDeleteSaleInvoicesService, + private validateBulkDeleteSaleInvoicesService: ValidateBulkDeleteSaleInvoicesService, ) {} /** @@ -78,6 +82,27 @@ export class SaleInvoiceApplication { return this.deleteSaleInvoiceService.deleteSaleInvoice(saleInvoiceId); } + /** + * Deletes multiple sale invoices. + * @param {number[]} saleInvoiceIds + * @return {Promise} + */ + public bulkDeleteSaleInvoices(saleInvoiceIds: number[]) { + return this.bulkDeleteSaleInvoicesService.bulkDeleteSaleInvoices( + saleInvoiceIds, + ); + } + + /** + * Validates which sale invoices can be deleted. + * @param {number[]} saleInvoiceIds + */ + public validateBulkDeleteSaleInvoices(saleInvoiceIds: number[]) { + return this.validateBulkDeleteSaleInvoicesService.validateBulkDeleteSaleInvoices( + saleInvoiceIds, + ); + } + /** * Retrieves the given sale invoice details. * @param {ISalesInvoicesFilter} filterDTO diff --git a/packages/server/src/modules/SaleInvoices/SaleInvoices.controller.ts b/packages/server/src/modules/SaleInvoices/SaleInvoices.controller.ts index 91166e1ed..ce40a3ef5 100644 --- a/packages/server/src/modules/SaleInvoices/SaleInvoices.controller.ts +++ b/packages/server/src/modules/SaleInvoices/SaleInvoices.controller.ts @@ -39,6 +39,10 @@ import { PaginatedResponseDto } from '@/common/dtos/PaginatedResults.dto'; import { SaleInvoiceStateResponseDto } from './dtos/SaleInvoiceState.dto'; import { GenerateSaleInvoiceSharableLinkResponseDto } from './dtos/GenerateSaleInvoiceSharableLinkResponse.dto'; import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; +import { + BulkDeleteDto, + ValidateBulkDeleteResponseDto, +} from '@/common/dtos/BulkDelete.dto'; @Controller('sale-invoices') @ApiTags('Sale Invoices') @@ -47,9 +51,43 @@ import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; @ApiExtraModels(SaleInvoiceStateResponseDto) @ApiExtraModels(GenerateSaleInvoiceSharableLinkResponseDto) @ApiCommonHeaders() +@ApiExtraModels(ValidateBulkDeleteResponseDto) export class SaleInvoicesController { constructor(private saleInvoiceApplication: SaleInvoiceApplication) { } + @Post('validate-bulk-delete') + @ApiOperation({ + summary: + 'Validates which sale invoices can be deleted and returns the results.', + }) + @ApiResponse({ + status: 200, + description: + 'Validation completed with counts and IDs of deletable and non-deletable sale invoices.', + schema: { + $ref: getSchemaPath(ValidateBulkDeleteResponseDto), + }, + }) + validateBulkDeleteSaleInvoices( + @Body() bulkDeleteDto: BulkDeleteDto, + ): Promise { + return this.saleInvoiceApplication.validateBulkDeleteSaleInvoices( + bulkDeleteDto.ids, + ); + } + + @Post('bulk-delete') + @ApiOperation({ summary: 'Deletes multiple sale invoices.' }) + @ApiResponse({ + status: 200, + description: 'Sale invoices deleted successfully', + }) + bulkDeleteSaleInvoices(@Body() bulkDeleteDto: BulkDeleteDto): Promise { + return this.saleInvoiceApplication.bulkDeleteSaleInvoices( + bulkDeleteDto.ids, + ); + } + @Post() @ApiOperation({ summary: 'Create a new sale invoice.' }) @ApiResponse({ diff --git a/packages/server/src/modules/SaleInvoices/SaleInvoices.module.ts b/packages/server/src/modules/SaleInvoices/SaleInvoices.module.ts index 50f3e614a..f21766f15 100644 --- a/packages/server/src/modules/SaleInvoices/SaleInvoices.module.ts +++ b/packages/server/src/modules/SaleInvoices/SaleInvoices.module.ts @@ -60,6 +60,8 @@ import { SaleInvoicesCost } from './SalesInvoicesCost'; import { SaleInvoicesExportable } from './commands/SaleInvoicesExportable'; import { SaleInvoicesImportable } from './commands/SaleInvoicesImportable'; import { PaymentLinksModule } from '../PaymentLinks/PaymentLinks.module'; +import { BulkDeleteSaleInvoicesService } from './BulkDeleteSaleInvoices.service'; +import { ValidateBulkDeleteSaleInvoicesService } from './ValidateBulkDeleteSaleInvoices.service'; @Module({ imports: [ @@ -126,6 +128,8 @@ import { PaymentLinksModule } from '../PaymentLinks/PaymentLinks.module'; SaleInvoicesCost, SaleInvoicesExportable, SaleInvoicesImportable, + BulkDeleteSaleInvoicesService, + ValidateBulkDeleteSaleInvoicesService, ], exports: [ GetSaleInvoice, diff --git a/packages/server/src/modules/SaleReceipts/BulkDeleteSaleReceipts.service.ts b/packages/server/src/modules/SaleReceipts/BulkDeleteSaleReceipts.service.ts new file mode 100644 index 000000000..6417e5b72 --- /dev/null +++ b/packages/server/src/modules/SaleReceipts/BulkDeleteSaleReceipts.service.ts @@ -0,0 +1,31 @@ +import { Injectable } from '@nestjs/common'; +import { Knex } from 'knex'; +import { PromisePool } from '@supercharge/promise-pool'; +import { castArray, uniq } from 'lodash'; +import { DeleteSaleReceipt } from './commands/DeleteSaleReceipt.service'; + +@Injectable() +export class BulkDeleteSaleReceiptsService { + constructor( + private readonly deleteSaleReceiptService: DeleteSaleReceipt, + ) { } + + async bulkDeleteSaleReceipts( + saleReceiptIds: number | number[], + trx?: Knex.Transaction, + ): Promise { + const receiptIds = uniq(castArray(saleReceiptIds)); + + const results = await PromisePool.withConcurrency(1) + .for(receiptIds) + .process(async (saleReceiptId: number) => { + await this.deleteSaleReceiptService.deleteSaleReceipt(saleReceiptId); + }); + + if (results.errors && results.errors.length > 0) { + throw results.errors[0].raw; + } + } +} + + diff --git a/packages/server/src/modules/SaleReceipts/SaleReceiptApplication.service.ts b/packages/server/src/modules/SaleReceipts/SaleReceiptApplication.service.ts index 33a83ca6e..5782ce896 100644 --- a/packages/server/src/modules/SaleReceipts/SaleReceiptApplication.service.ts +++ b/packages/server/src/modules/SaleReceipts/SaleReceiptApplication.service.ts @@ -22,6 +22,8 @@ import { EditSaleReceiptDto, } from './dtos/SaleReceipt.dto'; import { GetSaleReceiptMailStateService } from './queries/GetSaleReceiptMailState.service'; +import { BulkDeleteSaleReceiptsService } from './BulkDeleteSaleReceipts.service'; +import { ValidateBulkDeleteSaleReceiptsService } from './ValidateBulkDeleteSaleReceipts.service'; @Injectable() export class SaleReceiptApplication { @@ -36,7 +38,9 @@ export class SaleReceiptApplication { private getSaleReceiptStateService: GetSaleReceiptState, private saleReceiptNotifyByMailService: SaleReceiptMailNotification, private getSaleReceiptMailStateService: GetSaleReceiptMailStateService, - ) {} + private bulkDeleteSaleReceiptsService: BulkDeleteSaleReceiptsService, + private validateBulkDeleteSaleReceiptsService: ValidateBulkDeleteSaleReceiptsService, + ) { } /** * Creates a new sale receipt with associated entries. @@ -85,6 +89,26 @@ export class SaleReceiptApplication { return this.deleteSaleReceiptService.deleteSaleReceipt(saleReceiptId); } + /** + * Deletes multiple sale receipts. + * @param {number[]} saleReceiptIds + */ + public async bulkDeleteSaleReceipts(saleReceiptIds: number[]) { + return this.bulkDeleteSaleReceiptsService.bulkDeleteSaleReceipts( + saleReceiptIds, + ); + } + + /** + * Validates which sale receipts can be deleted. + * @param {number[]} saleReceiptIds + */ + public async validateBulkDeleteSaleReceipts(saleReceiptIds: number[]) { + return this.validateBulkDeleteSaleReceiptsService.validateBulkDeleteSaleReceipts( + saleReceiptIds, + ); + } + /** * Retrieve sales receipts paginated and filterable list. * @param {ISalesReceiptsFilter} filterDTO diff --git a/packages/server/src/modules/SaleReceipts/SaleReceipts.controller.ts b/packages/server/src/modules/SaleReceipts/SaleReceipts.controller.ts index c0b1dc959..90398c23a 100644 --- a/packages/server/src/modules/SaleReceipts/SaleReceipts.controller.ts +++ b/packages/server/src/modules/SaleReceipts/SaleReceipts.controller.ts @@ -32,6 +32,10 @@ import { SaleReceiptResponseDto } from './dtos/SaleReceiptResponse.dto'; import { PaginatedResponseDto } from '@/common/dtos/PaginatedResults.dto'; import { SaleReceiptStateResponseDto } from './dtos/SaleReceiptState.dto'; import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; +import { + BulkDeleteDto, + ValidateBulkDeleteResponseDto, +} from '@/common/dtos/BulkDelete.dto'; @Controller('sale-receipts') @ApiTags('Sale Receipts') @@ -39,8 +43,42 @@ import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; @ApiExtraModels(PaginatedResponseDto) @ApiExtraModels(SaleReceiptStateResponseDto) @ApiCommonHeaders() +@ApiExtraModels(ValidateBulkDeleteResponseDto) export class SaleReceiptsController { - constructor(private saleReceiptApplication: SaleReceiptApplication) {} + constructor(private saleReceiptApplication: SaleReceiptApplication) { } + + @Post('validate-bulk-delete') + @ApiOperation({ + summary: + 'Validates which sale receipts can be deleted and returns the results.', + }) + @ApiResponse({ + status: 200, + description: + 'Validation completed with counts and IDs of deletable and non-deletable sale receipts.', + schema: { + $ref: getSchemaPath(ValidateBulkDeleteResponseDto), + }, + }) + validateBulkDeleteSaleReceipts( + @Body() bulkDeleteDto: BulkDeleteDto, + ): Promise { + return this.saleReceiptApplication.validateBulkDeleteSaleReceipts( + bulkDeleteDto.ids, + ); + } + + @Post('bulk-delete') + @ApiOperation({ summary: 'Deletes multiple sale receipts.' }) + @ApiResponse({ + status: 200, + description: 'Sale receipts deleted successfully', + }) + bulkDeleteSaleReceipts(@Body() bulkDeleteDto: BulkDeleteDto): Promise { + return this.saleReceiptApplication.bulkDeleteSaleReceipts( + bulkDeleteDto.ids, + ); + } @Post() @ApiOperation({ summary: 'Create a new sale receipt.' }) diff --git a/packages/server/src/modules/SaleReceipts/SaleReceipts.module.ts b/packages/server/src/modules/SaleReceipts/SaleReceipts.module.ts index 1deb8aae6..faf83b892 100644 --- a/packages/server/src/modules/SaleReceipts/SaleReceipts.module.ts +++ b/packages/server/src/modules/SaleReceipts/SaleReceipts.module.ts @@ -40,6 +40,8 @@ import { SaleReceiptsImportable } from './commands/SaleReceiptsImportable'; import { GetSaleReceiptMailStateService } from './queries/GetSaleReceiptMailState.service'; import { GetSaleReceiptMailTemplateService } from './queries/GetSaleReceiptMailTemplate.service'; import { SaleReceiptAutoIncrementSubscriber } from './subscribers/SaleReceiptAutoIncrementSubscriber'; +import { BulkDeleteSaleReceiptsService } from './BulkDeleteSaleReceipts.service'; +import { ValidateBulkDeleteSaleReceiptsService } from './ValidateBulkDeleteSaleReceipts.service'; @Module({ controllers: [SaleReceiptsController], @@ -85,6 +87,8 @@ import { SaleReceiptAutoIncrementSubscriber } from './subscribers/SaleReceiptAut GetSaleReceiptMailStateService, GetSaleReceiptMailTemplateService, SaleReceiptAutoIncrementSubscriber, + BulkDeleteSaleReceiptsService, + ValidateBulkDeleteSaleReceiptsService, ], }) export class SaleReceiptsModule { } diff --git a/packages/server/src/modules/SaleReceipts/ValidateBulkDeleteSaleReceipts.service.ts b/packages/server/src/modules/SaleReceipts/ValidateBulkDeleteSaleReceipts.service.ts new file mode 100644 index 000000000..2bf86a9f9 --- /dev/null +++ b/packages/server/src/modules/SaleReceipts/ValidateBulkDeleteSaleReceipts.service.ts @@ -0,0 +1,54 @@ +import { Inject, Injectable } from '@nestjs/common'; +import { Knex } from 'knex'; +import { TENANCY_DB_CONNECTION } from '../Tenancy/TenancyDB/TenancyDB.constants'; +import { DeleteSaleReceipt } from './commands/DeleteSaleReceipt.service'; + +@Injectable() +export class ValidateBulkDeleteSaleReceiptsService { + constructor( + private readonly deleteSaleReceiptService: DeleteSaleReceipt, + @Inject(TENANCY_DB_CONNECTION) + private readonly tenantKnex: () => Knex, + ) {} + + public async validateBulkDeleteSaleReceipts( + saleReceiptIds: number[], + ): Promise<{ + deletableCount: number; + nonDeletableCount: number; + deletableIds: number[]; + nonDeletableIds: number[]; + }> { + const trx = await this.tenantKnex().transaction({ + isolationLevel: 'read uncommitted', + }); + + try { + const deletableIds: number[] = []; + const nonDeletableIds: number[] = []; + + for (const saleReceiptId of saleReceiptIds) { + try { + await this.deleteSaleReceiptService.deleteSaleReceipt(saleReceiptId); + deletableIds.push(saleReceiptId); + } catch (error) { + nonDeletableIds.push(saleReceiptId); + } + } + + await trx.rollback(); + + return { + deletableCount: deletableIds.length, + nonDeletableCount: nonDeletableIds.length, + deletableIds, + nonDeletableIds, + }; + } catch (error) { + await trx.rollback(); + throw error; + } + } +} + + diff --git a/packages/webapp/src/containers/Accounting/JournalsLanding/ManualJournalActionsBar.tsx b/packages/webapp/src/containers/Accounting/JournalsLanding/ManualJournalActionsBar.tsx index 39a451c6d..9aae2b897 100644 --- a/packages/webapp/src/containers/Accounting/JournalsLanding/ManualJournalActionsBar.tsx +++ b/packages/webapp/src/containers/Accounting/JournalsLanding/ManualJournalActionsBar.tsx @@ -30,6 +30,7 @@ import withManualJournalsActions from './withManualJournalsActions'; import withSettings from '@/containers/Settings/withSettings'; import withSettingsActions from '@/containers/Settings/withSettingsActions'; import withDialogActions from '@/containers/Dialog/withDialogActions'; +import withAlertActions from '@/containers/Alert/withAlertActions'; import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf'; import { compose } from '@/utils'; @@ -44,7 +45,7 @@ function ManualJournalActionsBar({ // #withManualJournals manualJournalsFilterConditions, - manualJournalsSelectedRows, + manualJournalsSelectedRows = [], // #withSettings manualJournalsTableSize, @@ -54,6 +55,9 @@ function ManualJournalActionsBar({ // #withDialogActions openDialog, + + // #withAlertActions + openAlert, }) { // History context. const history = useHistory(); @@ -72,7 +76,11 @@ function ManualJournalActionsBar({ history.push('/make-journal-entry'); }; // Handle delete button click. - const handleBulkDelete = () => { }; + const handleBulkDelete = () => { + openAlert('journals-bulk-delete', { + journalsIds: manualJournalsSelectedRows, + }); + }; // Handle tab change. const handleTabChange = (view) => { @@ -200,6 +208,7 @@ function ManualJournalActionsBar({ export default compose( withDialogActions, + withAlertActions, withManualJournalsActions, withSettingsActions, withManualJournals(({ manualJournalsTableState, manualJournalsSelectedRows }) => ({ diff --git a/packages/webapp/src/containers/Alerts/Invoices/InvoiceBulkDeleteAlert.tsx b/packages/webapp/src/containers/Alerts/Invoices/InvoiceBulkDeleteAlert.tsx index fda0b662b..80038bd3e 100644 --- a/packages/webapp/src/containers/Alerts/Invoices/InvoiceBulkDeleteAlert.tsx +++ b/packages/webapp/src/containers/Alerts/Invoices/InvoiceBulkDeleteAlert.tsx @@ -4,8 +4,8 @@ import { FormattedMessage as T } from '@/components'; import intl from 'react-intl-universal'; import { Intent, Alert } from '@blueprintjs/core'; import { queryCache } from 'react-query'; -import { AppToaster } from '@/components'; +import { AppToaster } from '@/components'; import { useBulkDeleteInvoices } from '@/hooks/query/invoices'; import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect'; import withAlertActions from '@/containers/Alert/withAlertActions'; diff --git a/packages/webapp/src/containers/Alerts/PaymentReceived/PaymentReceivedBulkDeleteAlert.tsx b/packages/webapp/src/containers/Alerts/PaymentReceived/PaymentReceivedBulkDeleteAlert.tsx index f690ea029..d65227ece 100644 --- a/packages/webapp/src/containers/Alerts/PaymentReceived/PaymentReceivedBulkDeleteAlert.tsx +++ b/packages/webapp/src/containers/Alerts/PaymentReceived/PaymentReceivedBulkDeleteAlert.tsx @@ -26,7 +26,6 @@ function PaymentReceivedBulkDeleteAlert({ const handleCancel = () => { closeAlert(name); }; - const handleConfirmBulkDelete = () => { bulkDeletePaymentReceives(paymentsReceivedIds) .then(() => { diff --git a/packages/webapp/src/containers/Expenses/ExpensesLanding/ExpenseActionsBar.tsx b/packages/webapp/src/containers/Expenses/ExpensesLanding/ExpenseActionsBar.tsx index ec01780a1..faa460978 100644 --- a/packages/webapp/src/containers/Expenses/ExpensesLanding/ExpenseActionsBar.tsx +++ b/packages/webapp/src/containers/Expenses/ExpensesLanding/ExpenseActionsBar.tsx @@ -34,6 +34,7 @@ import withExpensesActions from './withExpensesActions'; import withSettingsActions from '@/containers/Settings/withSettingsActions'; import withDialogActions from '@/containers/Dialog/withDialogActions'; import withSettings from '@/containers/Settings/withSettings'; +import withAlertActions from '@/containers/Alert/withAlertActions'; import { compose } from '@/utils'; import { isEmpty } from 'lodash'; @@ -47,7 +48,7 @@ function ExpensesActionsBar({ // #withExpenses expensesFilterConditions, - expensesSelectedRows, + expensesSelectedRows = [], // #withSettings expensesTableSize, @@ -57,6 +58,9 @@ function ExpensesActionsBar({ // #withDialogActions openDialog, + + // #withAlertActions + openAlert, }) { // History context. const history = useHistory(); @@ -75,7 +79,11 @@ function ExpensesActionsBar({ history.push('/expenses/new'); }; // Handle delete button click. - const handleBulkDelete = () => { }; + const handleBulkDelete = () => { + openAlert('expenses-bulk-delete', { + expensesIds: expensesSelectedRows, + }); + }; // Handles the tab chaning. const handleTabChange = (view) => { @@ -113,6 +121,7 @@ function ExpensesActionsBar({ icon={} text={} intent={Intent.DANGER} + onClick={handleBulkDelete} /> @@ -200,6 +209,7 @@ function ExpensesActionsBar({ export default compose( withDialogActions, + withAlertActions, withExpensesActions, withSettingsActions, withExpenses(({ expensesTableState, expensesSelectedRows }) => ({ diff --git a/packages/webapp/src/containers/Purchases/CreditNotes/CreditNotesLanding/withVendorsCreditNotes.tsx b/packages/webapp/src/containers/Purchases/CreditNotes/CreditNotesLanding/withVendorsCreditNotes.tsx index b03799f21..cd1130630 100644 --- a/packages/webapp/src/containers/Purchases/CreditNotes/CreditNotesLanding/withVendorsCreditNotes.tsx +++ b/packages/webapp/src/containers/Purchases/CreditNotes/CreditNotesLanding/withVendorsCreditNotes.tsx @@ -3,12 +3,15 @@ import { connect } from 'react-redux'; import { getVendorCreditTableStateFactory, isVendorCreditTableStateChangedFactory, + getVendorsCreditNoteSelectedRowsFactory, } from '@/store/VendorCredit/vendorCredit.selector'; export default (mapState) => { - const getVendorsCreditNoteTableState = getVendorCreditTableStateFactoryth(); + const getVendorsCreditNoteTableState = getVendorCreditTableStateFactory(); const isVendorsCreditNoteTableChanged = isVendorCreditTableStateChangedFactory(); + const getVendorsCreditNoteSelectedRows = + getVendorsCreditNoteSelectedRowsFactory(); const mapStateToProps = (state, props) => { const mapped = { diff --git a/packages/webapp/src/containers/Sales/PaymentsReceived/PaymentsLanding/PaymentsReceivedActionsBar.tsx b/packages/webapp/src/containers/Sales/PaymentsReceived/PaymentsLanding/PaymentsReceivedActionsBar.tsx index 412dc094e..1f4ed0c54 100644 --- a/packages/webapp/src/containers/Sales/PaymentsReceived/PaymentsLanding/PaymentsReceivedActionsBar.tsx +++ b/packages/webapp/src/containers/Sales/PaymentsReceived/PaymentsLanding/PaymentsReceivedActionsBar.tsx @@ -13,7 +13,7 @@ import { PopoverInteractionKind, Position, } from '@blueprintjs/core'; - +import { isEmpty } from 'lodash'; import { useHistory } from 'react-router-dom'; import { Icon, @@ -27,6 +27,7 @@ import { DashboardActionsBar, } from '@/components'; +import withAlertsActions from '@/containers/Alert/withAlertActions'; import withPaymentsReceived from './withPaymentsReceived'; import withPaymentsReceivedActions from './withPaymentsReceivedActions'; import withSettings from '@/containers/Settings/withSettings'; @@ -55,6 +56,7 @@ function PaymentsReceivedActionsBar({ // #withPaymentsReceived paymentFilterConditions, + paymentReceivesSelectedRows, // #withSettings paymentReceivesTableSize, @@ -67,6 +69,9 @@ function PaymentsReceivedActionsBar({ // #withDrawerActions openDrawer, + + // #withAlertsActions + openAlert, }) { // History context. const history = useHistory(); @@ -89,12 +94,10 @@ function PaymentsReceivedActionsBar({ const handleTabChange = (viewId) => { setPaymentReceivesTableState({ customViewId: viewId.id || null }); }; - // Handle click a refresh payment receives const handleRefreshBtnClick = () => { refresh(); }; - // Handle table row size change. const handleTableRowSizeChange = (size) => { addSetting('paymentReceives', 'tableSize', size); @@ -116,6 +119,24 @@ function PaymentsReceivedActionsBar({ openDrawer(DRAWERS.BRANDING_TEMPLATES, { resource: 'PaymentReceive' }); }; + if (!isEmpty(paymentReceivesSelectedRows)) { + const handleBulkDelete = () => { + openAlert('payments-received-bulk-delete', { paymentsReceivedIds: paymentReceivesSelectedRows }); + }; + return ( + + +