This commit is contained in:
Ahmed Bouhuolia
2025-11-17 17:04:25 +02:00
parent 2383091b6e
commit 2c64e1b8ab
41 changed files with 709 additions and 87 deletions

View File

@@ -41,6 +41,39 @@ import {
export class AccountsController { export class AccountsController {
constructor(private readonly accountsApplication: AccountsApplication) { } 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<ValidateBulkDeleteResponseDto> {
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<void> {
return this.accountsApplication.bulkDeleteAccounts(bulkDeleteDto.ids);
}
@Post() @Post()
@ApiOperation({ summary: 'Create an account' }) @ApiOperation({ summary: 'Create an account' })
@ApiResponse({ @ApiResponse({
@@ -88,37 +121,6 @@ export class AccountsController {
return this.accountsApplication.deleteAccount(id); 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<ValidateBulkDeleteResponseDto> {
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<void> {
return this.accountsApplication.bulkDeleteAccounts(bulkDeleteDto.ids);
}
@Post(':id/activate') @Post(':id/activate')
@ApiOperation({ summary: 'Activate the given account.' }) @ApiOperation({ summary: 'Activate the given account.' })
@ApiResponse({ @ApiResponse({

View File

@@ -9,6 +9,8 @@ import { Injectable } from '@nestjs/common';
import { GetBillsService } from './queries/GetBills.service'; import { GetBillsService } from './queries/GetBills.service';
import { CreateBillDto, EditBillDto } from './dtos/Bill.dto'; import { CreateBillDto, EditBillDto } from './dtos/Bill.dto';
import { GetBillPaymentTransactionsService } from './queries/GetBillPayments'; import { GetBillPaymentTransactionsService } from './queries/GetBillPayments';
import { BulkDeleteBillsService } from './BulkDeleteBills.service';
import { ValidateBulkDeleteBillsService } from './ValidateBulkDeleteBills.service';
// import { GetBillPayments } from './queries/GetBillPayments'; // import { GetBillPayments } from './queries/GetBillPayments';
// import { GetBills } from './queries/GetBills'; // import { GetBills } from './queries/GetBills';
@@ -23,7 +25,9 @@ export class BillsApplication {
private openBillService: OpenBillService, private openBillService: OpenBillService,
private getBillsService: GetBillsService, private getBillsService: GetBillsService,
private getBillPaymentTransactionsService: GetBillPaymentTransactionsService, private getBillPaymentTransactionsService: GetBillPaymentTransactionsService,
) {} private bulkDeleteBillsService: BulkDeleteBillsService,
private validateBulkDeleteBillsService: ValidateBulkDeleteBillsService,
) { }
/** /**
* Creates a new bill with associated GL entries. * Creates a new bill with associated GL entries.
@@ -53,6 +57,22 @@ export class BillsApplication {
return this.deleteBillService.deleteBill(billId); 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. * Retrieve bills data table list.
* @param {IBillsFilter} billsFilter - * @param {IBillsFilter} billsFilter -

View File

@@ -22,14 +22,47 @@ import { CreateBillDto, EditBillDto } from './dtos/Bill.dto';
import { BillResponseDto } from './dtos/BillResponse.dto'; import { BillResponseDto } from './dtos/BillResponse.dto';
import { PaginatedResponseDto } from '@/common/dtos/PaginatedResults.dto'; import { PaginatedResponseDto } from '@/common/dtos/PaginatedResults.dto';
import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders';
import {
BulkDeleteDto,
ValidateBulkDeleteResponseDto,
} from '@/common/dtos/BulkDelete.dto';
@Controller('bills') @Controller('bills')
@ApiTags('Bills') @ApiTags('Bills')
@ApiExtraModels(BillResponseDto) @ApiExtraModels(BillResponseDto)
@ApiExtraModels(PaginatedResponseDto) @ApiExtraModels(PaginatedResponseDto)
@ApiCommonHeaders() @ApiCommonHeaders()
@ApiExtraModels(ValidateBulkDeleteResponseDto)
export class BillsController { 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<ValidateBulkDeleteResponseDto> {
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<void> {
return this.billsApplication.bulkDeleteBills(bulkDeleteDto.ids);
}
@Post() @Post()
@ApiOperation({ summary: 'Create a new bill.' }) @ApiOperation({ summary: 'Create a new bill.' })

View File

@@ -29,6 +29,8 @@ import { InventoryCostModule } from '../InventoryCost/InventoryCost.module';
import { BillsExportable } from './commands/BillsExportable'; import { BillsExportable } from './commands/BillsExportable';
import { BillsImportable } from './commands/BillsImportable'; import { BillsImportable } from './commands/BillsImportable';
import { GetBillPaymentTransactionsService } from './queries/GetBillPayments'; import { GetBillPaymentTransactionsService } from './queries/GetBillPayments';
import { BulkDeleteBillsService } from './BulkDeleteBills.service';
import { ValidateBulkDeleteBillsService } from './ValidateBulkDeleteBills.service';
@Module({ @Module({
imports: [ imports: [
@@ -63,8 +65,10 @@ import { GetBillPaymentTransactionsService } from './queries/GetBillPayments';
BillsExportable, BillsExportable,
BillsImportable, BillsImportable,
GetBillPaymentTransactionsService, GetBillPaymentTransactionsService,
BulkDeleteBillsService,
ValidateBulkDeleteBillsService,
], ],
controllers: [BillsController], controllers: [BillsController],
exports: [BillsExportable, BillsImportable], exports: [BillsExportable, BillsImportable],
}) })
export class BillsModule {} export class BillsModule { }

View File

@@ -21,13 +21,51 @@ import { CreateExpenseDto, EditExpenseDto } from './dtos/Expense.dto';
import { PaginatedResponseDto } from '@/common/dtos/PaginatedResults.dto'; import { PaginatedResponseDto } from '@/common/dtos/PaginatedResults.dto';
import { ExpenseResponseDto } from './dtos/ExpenseResponse.dto'; import { ExpenseResponseDto } from './dtos/ExpenseResponse.dto';
import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders';
import {
BulkDeleteDto,
ValidateBulkDeleteResponseDto,
} from '@/common/dtos/BulkDelete.dto';
@Controller('expenses') @Controller('expenses')
@ApiTags('Expenses') @ApiTags('Expenses')
@ApiExtraModels(PaginatedResponseDto, ExpenseResponseDto) @ApiExtraModels(
PaginatedResponseDto,
ExpenseResponseDto,
ValidateBulkDeleteResponseDto,
)
@ApiCommonHeaders() @ApiCommonHeaders()
export class ExpensesController { 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<ValidateBulkDeleteResponseDto> {
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. * Create a new expense transaction.

View File

@@ -19,6 +19,8 @@ import { GetExpensesService } from './queries/GetExpenses.service';
import { DynamicListModule } from '../DynamicListing/DynamicList.module'; import { DynamicListModule } from '../DynamicListing/DynamicList.module';
import { ExpensesExportable } from './ExpensesExportable'; import { ExpensesExportable } from './ExpensesExportable';
import { ExpensesImportable } from './ExpensesImportable'; import { ExpensesImportable } from './ExpensesImportable';
import { BulkDeleteExpensesService } from './BulkDeleteExpenses.service';
import { ValidateBulkDeleteExpensesService } from './ValidateBulkDeleteExpenses.service';
@Module({ @Module({
imports: [LedgerModule, BranchesModule, DynamicListModule], imports: [LedgerModule, BranchesModule, DynamicListModule],
@@ -41,6 +43,8 @@ import { ExpensesImportable } from './ExpensesImportable';
GetExpensesService, GetExpensesService,
ExpensesExportable, ExpensesExportable,
ExpensesImportable, ExpensesImportable,
BulkDeleteExpensesService,
ValidateBulkDeleteExpensesService,
], ],
}) })
export class ExpensesModule {} export class ExpensesModule {}

View File

@@ -7,6 +7,8 @@ import { GetExpenseService } from './queries/GetExpense.service';
import { IExpensesFilter } from './interfaces/Expenses.interface'; import { IExpensesFilter } from './interfaces/Expenses.interface';
import { GetExpensesService } from './queries/GetExpenses.service'; import { GetExpensesService } from './queries/GetExpenses.service';
import { CreateExpenseDto, EditExpenseDto } from './dtos/Expense.dto'; import { CreateExpenseDto, EditExpenseDto } from './dtos/Expense.dto';
import { BulkDeleteExpensesService } from './BulkDeleteExpenses.service';
import { ValidateBulkDeleteExpensesService } from './ValidateBulkDeleteExpenses.service';
@Injectable() @Injectable()
export class ExpensesApplication { export class ExpensesApplication {
@@ -17,6 +19,8 @@ export class ExpensesApplication {
private readonly publishExpenseService: PublishExpense, private readonly publishExpenseService: PublishExpense,
private readonly getExpenseService: GetExpenseService, private readonly getExpenseService: GetExpenseService,
private readonly getExpensesService: GetExpensesService, private readonly getExpensesService: GetExpensesService,
private readonly bulkDeleteExpensesService: BulkDeleteExpensesService,
private readonly validateBulkDeleteExpensesService: ValidateBulkDeleteExpensesService,
) {} ) {}
/** /**
@@ -47,6 +51,24 @@ export class ExpensesApplication {
return this.deleteExpenseService.deleteExpense(expenseId); 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. * Publishes the given expense.
* @param {number} expenseId - Expense id. * @param {number} expenseId - Expense id.

View File

@@ -25,13 +25,53 @@ import {
import { IManualJournalsFilter } from './types/ManualJournals.types'; import { IManualJournalsFilter } from './types/ManualJournals.types';
import { ManualJournalResponseDto } from './dtos/ManualJournalResponse.dto'; import { ManualJournalResponseDto } from './dtos/ManualJournalResponse.dto';
import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders';
import {
BulkDeleteDto,
ValidateBulkDeleteResponseDto,
} from '@/common/dtos/BulkDelete.dto';
@Controller('manual-journals') @Controller('manual-journals')
@ApiTags('Manual Journals') @ApiTags('Manual Journals')
@ApiExtraModels(ManualJournalResponseDto) @ApiExtraModels(ManualJournalResponseDto)
@ApiExtraModels(ValidateBulkDeleteResponseDto)
@ApiCommonHeaders() @ApiCommonHeaders()
export class ManualJournalsController { 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<ValidateBulkDeleteResponseDto> {
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<void> {
return this.manualJournalsApplication.bulkDeleteManualJournals(
bulkDeleteDto.ids,
);
}
@Post() @Post()
@ApiOperation({ summary: 'Create a new manual journal.' }) @ApiOperation({ summary: 'Create a new manual journal.' })

View File

@@ -19,6 +19,8 @@ import { ManualJournalsExportable } from './commands/ManualJournalExportable';
import { ManualJournalImportable } from './commands/ManualJournalsImport'; import { ManualJournalImportable } from './commands/ManualJournalsImport';
import { GetManualJournals } from './queries/GetManualJournals.service'; import { GetManualJournals } from './queries/GetManualJournals.service';
import { DynamicListModule } from '../DynamicListing/DynamicList.module'; import { DynamicListModule } from '../DynamicListing/DynamicList.module';
import { BulkDeleteManualJournalsService } from './BulkDeleteManualJournals.service';
import { ValidateBulkDeleteManualJournalsService } from './ValidateBulkDeleteManualJournals.service';
@Module({ @Module({
imports: [BranchesModule, LedgerModule, DynamicListModule], imports: [BranchesModule, LedgerModule, DynamicListModule],
@@ -41,6 +43,8 @@ import { DynamicListModule } from '../DynamicListing/DynamicList.module';
ManualJournalWriteGLSubscriber, ManualJournalWriteGLSubscriber,
ManualJournalsExportable, ManualJournalsExportable,
ManualJournalImportable, ManualJournalImportable,
BulkDeleteManualJournalsService,
ValidateBulkDeleteManualJournalsService,
], ],
exports: [ManualJournalsExportable, ManualJournalImportable], exports: [ManualJournalsExportable, ManualJournalImportable],
}) })

View File

@@ -10,6 +10,8 @@ import {
EditManualJournalDto, EditManualJournalDto,
} from './dtos/ManualJournal.dto'; } from './dtos/ManualJournal.dto';
import { GetManualJournals } from './queries/GetManualJournals.service'; import { GetManualJournals } from './queries/GetManualJournals.service';
import { BulkDeleteManualJournalsService } from './BulkDeleteManualJournals.service';
import { ValidateBulkDeleteManualJournalsService } from './ValidateBulkDeleteManualJournals.service';
// import { GetManualJournals } from './queries/GetManualJournals'; // import { GetManualJournals } from './queries/GetManualJournals';
@Injectable() @Injectable()
@@ -21,6 +23,8 @@ export class ManualJournalsApplication {
private publishManualJournalService: PublishManualJournal, private publishManualJournalService: PublishManualJournal,
private getManualJournalService: GetManualJournal, private getManualJournalService: GetManualJournal,
private getManualJournalsService: GetManualJournals, private getManualJournalsService: GetManualJournals,
private bulkDeleteManualJournalsService: BulkDeleteManualJournalsService,
private validateBulkDeleteManualJournalsService: ValidateBulkDeleteManualJournalsService,
) {} ) {}
/** /**
@@ -57,6 +61,26 @@ export class ManualJournalsApplication {
return this.deleteManualJournalService.deleteManualJournal(manualJournalId); 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. * Publish the given manual journal.
* @param {number} manualJournalId - Manual journal id. * @param {number} manualJournalId - Manual journal id.

View File

@@ -18,6 +18,8 @@ import {
} from './dtos/PaymentReceived.dto'; } from './dtos/PaymentReceived.dto';
import { PaymentsReceivedPagesService } from './queries/PaymentsReceivedPages.service'; import { PaymentsReceivedPagesService } from './queries/PaymentsReceivedPages.service';
import { GetPaymentReceivedMailState } from './queries/GetPaymentReceivedMailState.service'; import { GetPaymentReceivedMailState } from './queries/GetPaymentReceivedMailState.service';
import { BulkDeletePaymentReceivedService } from './BulkDeletePaymentReceived.service';
import { ValidateBulkDeletePaymentReceivedService } from './ValidateBulkDeletePaymentReceived.service';
@Injectable() @Injectable()
export class PaymentReceivesApplication { export class PaymentReceivesApplication {
@@ -33,7 +35,9 @@ export class PaymentReceivesApplication {
private getPaymentReceivePdfService: GetPaymentReceivedPdfService, private getPaymentReceivePdfService: GetPaymentReceivedPdfService,
private getPaymentReceivedStateService: GetPaymentReceivedStateService, private getPaymentReceivedStateService: GetPaymentReceivedStateService,
private paymentsReceivedPagesService: PaymentsReceivedPagesService, private paymentsReceivedPagesService: PaymentsReceivedPagesService,
) {} private bulkDeletePaymentReceivedService: BulkDeletePaymentReceivedService,
private validateBulkDeletePaymentReceivedService: ValidateBulkDeletePaymentReceivedService,
) { }
/** /**
* Creates a new payment receive. * 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. * Retrieve payment receives paginated and filterable.
* @param {number} tenantId * @param {number} tenantId

View File

@@ -32,15 +32,20 @@ import { PaymentReceivedResponseDto } from './dtos/PaymentReceivedResponse.dto';
import { PaginatedResponseDto } from '@/common/dtos/PaginatedResults.dto'; import { PaginatedResponseDto } from '@/common/dtos/PaginatedResults.dto';
import { PaymentReceivedStateResponseDto } from './dtos/PaymentReceivedStateResponse.dto'; import { PaymentReceivedStateResponseDto } from './dtos/PaymentReceivedStateResponse.dto';
import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders';
import {
BulkDeleteDto,
ValidateBulkDeleteResponseDto,
} from '@/common/dtos/BulkDelete.dto';
@Controller('payments-received') @Controller('payments-received')
@ApiTags('Payments Received') @ApiTags('Payments Received')
@ApiExtraModels(PaymentReceivedResponseDto) @ApiExtraModels(PaymentReceivedResponseDto)
@ApiExtraModels(PaginatedResponseDto) @ApiExtraModels(PaginatedResponseDto)
@ApiExtraModels(PaymentReceivedStateResponseDto) @ApiExtraModels(PaymentReceivedStateResponseDto)
@ApiExtraModels(ValidateBulkDeleteResponseDto)
@ApiCommonHeaders() @ApiCommonHeaders()
export class PaymentReceivesController { export class PaymentReceivesController {
constructor(private paymentReceivesApplication: PaymentReceivesApplication) {} constructor(private paymentReceivesApplication: PaymentReceivesApplication) { }
@Post(':id/mail') @Post(':id/mail')
@HttpCode(200) @HttpCode(200)
@@ -143,6 +148,39 @@ export class PaymentReceivesController {
return this.paymentReceivesApplication.getPaymentsReceived(filterDTO); 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<ValidateBulkDeleteResponseDto> {
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') @Get('state')
@ApiOperation({ summary: 'Retrieves the payment received state.' }) @ApiOperation({ summary: 'Retrieves the payment received state.' })
@ApiResponse({ @ApiResponse({

View File

@@ -39,6 +39,8 @@ import { PaymentsReceivedImportable } from './commands/PaymentsReceivedImportabl
import { PaymentsReceivedPagesService } from './queries/PaymentsReceivedPages.service'; import { PaymentsReceivedPagesService } from './queries/PaymentsReceivedPages.service';
import { GetPaymentReceivedMailTemplate } from './queries/GetPaymentReceivedMailTemplate.service'; import { GetPaymentReceivedMailTemplate } from './queries/GetPaymentReceivedMailTemplate.service';
import { GetPaymentReceivedMailState } from './queries/GetPaymentReceivedMailState.service'; import { GetPaymentReceivedMailState } from './queries/GetPaymentReceivedMailState.service';
import { BulkDeletePaymentReceivedService } from './BulkDeletePaymentReceived.service';
import { ValidateBulkDeletePaymentReceivedService } from './ValidateBulkDeletePaymentReceived.service';
@Module({ @Module({
controllers: [PaymentReceivesController], controllers: [PaymentReceivesController],
@@ -68,7 +70,9 @@ import { GetPaymentReceivedMailState } from './queries/GetPaymentReceivedMailSta
PaymentsReceivedImportable, PaymentsReceivedImportable,
PaymentsReceivedPagesService, PaymentsReceivedPagesService,
GetPaymentReceivedMailTemplate, GetPaymentReceivedMailTemplate,
GetPaymentReceivedMailState GetPaymentReceivedMailState,
BulkDeletePaymentReceivedService,
ValidateBulkDeletePaymentReceivedService,
], ],
exports: [ exports: [
PaymentReceivesApplication, PaymentReceivesApplication,
@@ -76,7 +80,7 @@ import { GetPaymentReceivedMailState } from './queries/GetPaymentReceivedMailSta
PaymentReceivedGLEntries, PaymentReceivedGLEntries,
PaymentsReceivedExportable, PaymentsReceivedExportable,
PaymentsReceivedImportable, PaymentsReceivedImportable,
PaymentReceivedValidators PaymentReceivedValidators,
], ],
imports: [ imports: [
ChromiumlyTenancyModule, ChromiumlyTenancyModule,

View File

@@ -19,6 +19,8 @@ import {
EditSaleEstimateDto, EditSaleEstimateDto,
} from './dtos/SaleEstimate.dto'; } from './dtos/SaleEstimate.dto';
import { GetSaleEstimateMailStateService } from './queries/GetSaleEstimateMailState.service'; import { GetSaleEstimateMailStateService } from './queries/GetSaleEstimateMailState.service';
import { BulkDeleteSaleEstimatesService } from './BulkDeleteSaleEstimates.service';
import { ValidateBulkDeleteSaleEstimatesService } from './ValidateBulkDeleteSaleEstimates.service';
@Injectable() @Injectable()
export class SaleEstimatesApplication { export class SaleEstimatesApplication {
@@ -35,6 +37,8 @@ export class SaleEstimatesApplication {
private readonly getSaleEstimateStateService: GetSaleEstimateState, private readonly getSaleEstimateStateService: GetSaleEstimateState,
private readonly saleEstimatesPdfService: GetSaleEstimatePdf, private readonly saleEstimatesPdfService: GetSaleEstimatePdf,
private readonly getSaleEstimateMailStateService: GetSaleEstimateMailStateService, private readonly getSaleEstimateMailStateService: GetSaleEstimateMailStateService,
private readonly bulkDeleteSaleEstimatesService: BulkDeleteSaleEstimatesService,
private readonly validateBulkDeleteSaleEstimatesService: ValidateBulkDeleteSaleEstimatesService,
) {} ) {}
/** /**
@@ -68,6 +72,27 @@ export class SaleEstimatesApplication {
return this.deleteSaleEstimateService.deleteEstimate(estimateId); return this.deleteSaleEstimateService.deleteEstimate(estimateId);
} }
/**
* Deletes multiple sale estimates.
* @param {number[]} saleEstimateIds
* @return {Promise<void>}
*/
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. * Retrieves the given sale estimate.
* @param {number} estimateId - Sale estimate ID. * @param {number} estimateId - Sale estimate ID.

View File

@@ -36,6 +36,10 @@ import { SaleEstimateResponseDto } from './dtos/SaleEstimateResponse.dto';
import { PaginatedResponseDto } from '@/common/dtos/PaginatedResults.dto'; import { PaginatedResponseDto } from '@/common/dtos/PaginatedResults.dto';
import { SaleEstiamteStateResponseDto } from './dtos/SaleEstimateStateResponse.dto'; import { SaleEstiamteStateResponseDto } from './dtos/SaleEstimateStateResponse.dto';
import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders';
import {
BulkDeleteDto,
ValidateBulkDeleteResponseDto,
} from '@/common/dtos/BulkDelete.dto';
@Controller('sale-estimates') @Controller('sale-estimates')
@ApiTags('Sale Estimates') @ApiTags('Sale Estimates')
@@ -43,13 +47,49 @@ import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders';
@ApiExtraModels(PaginatedResponseDto) @ApiExtraModels(PaginatedResponseDto)
@ApiExtraModels(SaleEstiamteStateResponseDto) @ApiExtraModels(SaleEstiamteStateResponseDto)
@ApiCommonHeaders() @ApiCommonHeaders()
@ApiExtraModels(ValidateBulkDeleteResponseDto)
export class SaleEstimatesController { 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<ValidateBulkDeleteResponseDto> {
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<void> {
return this.saleEstimatesApplication.bulkDeleteSaleEstimates(
bulkDeleteDto.ids,
);
}
/** /**
* @param {SaleEstimatesApplication} saleEstimatesApplication - Sale estimates application. * @param {SaleEstimatesApplication} saleEstimatesApplication - Sale estimates application.
*/ */
constructor( constructor(
private readonly saleEstimatesApplication: SaleEstimatesApplication, private readonly saleEstimatesApplication: SaleEstimatesApplication,
) {} ) { }
@Post() @Post()
@ApiOperation({ summary: 'Create a new sale estimate.' }) @ApiOperation({ summary: 'Create a new sale estimate.' })

View File

@@ -40,6 +40,8 @@ import { SaleEstimatesImportable } from './SaleEstimatesImportable';
import { GetSaleEstimateMailStateService } from './queries/GetSaleEstimateMailState.service'; import { GetSaleEstimateMailStateService } from './queries/GetSaleEstimateMailState.service';
import { GetSaleEstimateMailTemplateService } from './queries/GetSaleEstimateMailTemplate.service'; import { GetSaleEstimateMailTemplateService } from './queries/GetSaleEstimateMailTemplate.service';
import { SaleEstimateAutoIncrementSubscriber } from './subscribers/SaleEstimateAutoIncrementSubscriber'; import { SaleEstimateAutoIncrementSubscriber } from './subscribers/SaleEstimateAutoIncrementSubscriber';
import { BulkDeleteSaleEstimatesService } from './BulkDeleteSaleEstimates.service';
import { ValidateBulkDeleteSaleEstimatesService } from './ValidateBulkDeleteSaleEstimates.service';
@Module({ @Module({
imports: [ imports: [
@@ -85,6 +87,8 @@ import { SaleEstimateAutoIncrementSubscriber } from './subscribers/SaleEstimateA
GetSaleEstimateMailStateService, GetSaleEstimateMailStateService,
GetSaleEstimateMailTemplateService, GetSaleEstimateMailTemplateService,
SaleEstimateAutoIncrementSubscriber, SaleEstimateAutoIncrementSubscriber,
BulkDeleteSaleEstimatesService,
ValidateBulkDeleteSaleEstimatesService,
], ],
exports: [ exports: [
SaleEstimatesExportable, SaleEstimatesExportable,

View File

@@ -23,6 +23,8 @@ import {
EditSaleInvoiceDto, EditSaleInvoiceDto,
} from './dtos/SaleInvoice.dto'; } from './dtos/SaleInvoice.dto';
import { GenerateShareLink } from './commands/GenerateInvoicePaymentLink.service'; import { GenerateShareLink } from './commands/GenerateInvoicePaymentLink.service';
import { BulkDeleteSaleInvoicesService } from './BulkDeleteSaleInvoices.service';
import { ValidateBulkDeleteSaleInvoicesService } from './ValidateBulkDeleteSaleInvoices.service';
@Injectable() @Injectable()
export class SaleInvoiceApplication { export class SaleInvoiceApplication {
@@ -41,6 +43,8 @@ export class SaleInvoiceApplication {
private sendSaleInvoiceMailService: SendSaleInvoiceMail, private sendSaleInvoiceMailService: SendSaleInvoiceMail,
private getSaleInvoiceMailStateService: GetSaleInvoiceMailState, private getSaleInvoiceMailStateService: GetSaleInvoiceMailState,
private generateShareLinkService: GenerateShareLink, private generateShareLinkService: GenerateShareLink,
private bulkDeleteSaleInvoicesService: BulkDeleteSaleInvoicesService,
private validateBulkDeleteSaleInvoicesService: ValidateBulkDeleteSaleInvoicesService,
) {} ) {}
/** /**
@@ -78,6 +82,27 @@ export class SaleInvoiceApplication {
return this.deleteSaleInvoiceService.deleteSaleInvoice(saleInvoiceId); return this.deleteSaleInvoiceService.deleteSaleInvoice(saleInvoiceId);
} }
/**
* Deletes multiple sale invoices.
* @param {number[]} saleInvoiceIds
* @return {Promise<void>}
*/
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. * Retrieves the given sale invoice details.
* @param {ISalesInvoicesFilter} filterDTO * @param {ISalesInvoicesFilter} filterDTO

View File

@@ -39,6 +39,10 @@ import { PaginatedResponseDto } from '@/common/dtos/PaginatedResults.dto';
import { SaleInvoiceStateResponseDto } from './dtos/SaleInvoiceState.dto'; import { SaleInvoiceStateResponseDto } from './dtos/SaleInvoiceState.dto';
import { GenerateSaleInvoiceSharableLinkResponseDto } from './dtos/GenerateSaleInvoiceSharableLinkResponse.dto'; import { GenerateSaleInvoiceSharableLinkResponseDto } from './dtos/GenerateSaleInvoiceSharableLinkResponse.dto';
import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders';
import {
BulkDeleteDto,
ValidateBulkDeleteResponseDto,
} from '@/common/dtos/BulkDelete.dto';
@Controller('sale-invoices') @Controller('sale-invoices')
@ApiTags('Sale Invoices') @ApiTags('Sale Invoices')
@@ -47,9 +51,43 @@ import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders';
@ApiExtraModels(SaleInvoiceStateResponseDto) @ApiExtraModels(SaleInvoiceStateResponseDto)
@ApiExtraModels(GenerateSaleInvoiceSharableLinkResponseDto) @ApiExtraModels(GenerateSaleInvoiceSharableLinkResponseDto)
@ApiCommonHeaders() @ApiCommonHeaders()
@ApiExtraModels(ValidateBulkDeleteResponseDto)
export class SaleInvoicesController { export class SaleInvoicesController {
constructor(private saleInvoiceApplication: SaleInvoiceApplication) { } 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<ValidateBulkDeleteResponseDto> {
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<void> {
return this.saleInvoiceApplication.bulkDeleteSaleInvoices(
bulkDeleteDto.ids,
);
}
@Post() @Post()
@ApiOperation({ summary: 'Create a new sale invoice.' }) @ApiOperation({ summary: 'Create a new sale invoice.' })
@ApiResponse({ @ApiResponse({

View File

@@ -60,6 +60,8 @@ import { SaleInvoicesCost } from './SalesInvoicesCost';
import { SaleInvoicesExportable } from './commands/SaleInvoicesExportable'; import { SaleInvoicesExportable } from './commands/SaleInvoicesExportable';
import { SaleInvoicesImportable } from './commands/SaleInvoicesImportable'; import { SaleInvoicesImportable } from './commands/SaleInvoicesImportable';
import { PaymentLinksModule } from '../PaymentLinks/PaymentLinks.module'; import { PaymentLinksModule } from '../PaymentLinks/PaymentLinks.module';
import { BulkDeleteSaleInvoicesService } from './BulkDeleteSaleInvoices.service';
import { ValidateBulkDeleteSaleInvoicesService } from './ValidateBulkDeleteSaleInvoices.service';
@Module({ @Module({
imports: [ imports: [
@@ -126,6 +128,8 @@ import { PaymentLinksModule } from '../PaymentLinks/PaymentLinks.module';
SaleInvoicesCost, SaleInvoicesCost,
SaleInvoicesExportable, SaleInvoicesExportable,
SaleInvoicesImportable, SaleInvoicesImportable,
BulkDeleteSaleInvoicesService,
ValidateBulkDeleteSaleInvoicesService,
], ],
exports: [ exports: [
GetSaleInvoice, GetSaleInvoice,

View File

@@ -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<void> {
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;
}
}
}

View File

@@ -22,6 +22,8 @@ import {
EditSaleReceiptDto, EditSaleReceiptDto,
} from './dtos/SaleReceipt.dto'; } from './dtos/SaleReceipt.dto';
import { GetSaleReceiptMailStateService } from './queries/GetSaleReceiptMailState.service'; import { GetSaleReceiptMailStateService } from './queries/GetSaleReceiptMailState.service';
import { BulkDeleteSaleReceiptsService } from './BulkDeleteSaleReceipts.service';
import { ValidateBulkDeleteSaleReceiptsService } from './ValidateBulkDeleteSaleReceipts.service';
@Injectable() @Injectable()
export class SaleReceiptApplication { export class SaleReceiptApplication {
@@ -36,7 +38,9 @@ export class SaleReceiptApplication {
private getSaleReceiptStateService: GetSaleReceiptState, private getSaleReceiptStateService: GetSaleReceiptState,
private saleReceiptNotifyByMailService: SaleReceiptMailNotification, private saleReceiptNotifyByMailService: SaleReceiptMailNotification,
private getSaleReceiptMailStateService: GetSaleReceiptMailStateService, private getSaleReceiptMailStateService: GetSaleReceiptMailStateService,
) {} private bulkDeleteSaleReceiptsService: BulkDeleteSaleReceiptsService,
private validateBulkDeleteSaleReceiptsService: ValidateBulkDeleteSaleReceiptsService,
) { }
/** /**
* Creates a new sale receipt with associated entries. * Creates a new sale receipt with associated entries.
@@ -85,6 +89,26 @@ export class SaleReceiptApplication {
return this.deleteSaleReceiptService.deleteSaleReceipt(saleReceiptId); 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. * Retrieve sales receipts paginated and filterable list.
* @param {ISalesReceiptsFilter} filterDTO * @param {ISalesReceiptsFilter} filterDTO

View File

@@ -32,6 +32,10 @@ import { SaleReceiptResponseDto } from './dtos/SaleReceiptResponse.dto';
import { PaginatedResponseDto } from '@/common/dtos/PaginatedResults.dto'; import { PaginatedResponseDto } from '@/common/dtos/PaginatedResults.dto';
import { SaleReceiptStateResponseDto } from './dtos/SaleReceiptState.dto'; import { SaleReceiptStateResponseDto } from './dtos/SaleReceiptState.dto';
import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders'; import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders';
import {
BulkDeleteDto,
ValidateBulkDeleteResponseDto,
} from '@/common/dtos/BulkDelete.dto';
@Controller('sale-receipts') @Controller('sale-receipts')
@ApiTags('Sale Receipts') @ApiTags('Sale Receipts')
@@ -39,8 +43,42 @@ import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders';
@ApiExtraModels(PaginatedResponseDto) @ApiExtraModels(PaginatedResponseDto)
@ApiExtraModels(SaleReceiptStateResponseDto) @ApiExtraModels(SaleReceiptStateResponseDto)
@ApiCommonHeaders() @ApiCommonHeaders()
@ApiExtraModels(ValidateBulkDeleteResponseDto)
export class SaleReceiptsController { 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<ValidateBulkDeleteResponseDto> {
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<void> {
return this.saleReceiptApplication.bulkDeleteSaleReceipts(
bulkDeleteDto.ids,
);
}
@Post() @Post()
@ApiOperation({ summary: 'Create a new sale receipt.' }) @ApiOperation({ summary: 'Create a new sale receipt.' })

View File

@@ -40,6 +40,8 @@ import { SaleReceiptsImportable } from './commands/SaleReceiptsImportable';
import { GetSaleReceiptMailStateService } from './queries/GetSaleReceiptMailState.service'; import { GetSaleReceiptMailStateService } from './queries/GetSaleReceiptMailState.service';
import { GetSaleReceiptMailTemplateService } from './queries/GetSaleReceiptMailTemplate.service'; import { GetSaleReceiptMailTemplateService } from './queries/GetSaleReceiptMailTemplate.service';
import { SaleReceiptAutoIncrementSubscriber } from './subscribers/SaleReceiptAutoIncrementSubscriber'; import { SaleReceiptAutoIncrementSubscriber } from './subscribers/SaleReceiptAutoIncrementSubscriber';
import { BulkDeleteSaleReceiptsService } from './BulkDeleteSaleReceipts.service';
import { ValidateBulkDeleteSaleReceiptsService } from './ValidateBulkDeleteSaleReceipts.service';
@Module({ @Module({
controllers: [SaleReceiptsController], controllers: [SaleReceiptsController],
@@ -85,6 +87,8 @@ import { SaleReceiptAutoIncrementSubscriber } from './subscribers/SaleReceiptAut
GetSaleReceiptMailStateService, GetSaleReceiptMailStateService,
GetSaleReceiptMailTemplateService, GetSaleReceiptMailTemplateService,
SaleReceiptAutoIncrementSubscriber, SaleReceiptAutoIncrementSubscriber,
BulkDeleteSaleReceiptsService,
ValidateBulkDeleteSaleReceiptsService,
], ],
}) })
export class SaleReceiptsModule { } export class SaleReceiptsModule { }

View File

@@ -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;
}
}
}

View File

@@ -30,6 +30,7 @@ import withManualJournalsActions from './withManualJournalsActions';
import withSettings from '@/containers/Settings/withSettings'; import withSettings from '@/containers/Settings/withSettings';
import withSettingsActions from '@/containers/Settings/withSettingsActions'; import withSettingsActions from '@/containers/Settings/withSettingsActions';
import withDialogActions from '@/containers/Dialog/withDialogActions'; import withDialogActions from '@/containers/Dialog/withDialogActions';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf'; import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
import { compose } from '@/utils'; import { compose } from '@/utils';
@@ -44,7 +45,7 @@ function ManualJournalActionsBar({
// #withManualJournals // #withManualJournals
manualJournalsFilterConditions, manualJournalsFilterConditions,
manualJournalsSelectedRows, manualJournalsSelectedRows = [],
// #withSettings // #withSettings
manualJournalsTableSize, manualJournalsTableSize,
@@ -54,6 +55,9 @@ function ManualJournalActionsBar({
// #withDialogActions // #withDialogActions
openDialog, openDialog,
// #withAlertActions
openAlert,
}) { }) {
// History context. // History context.
const history = useHistory(); const history = useHistory();
@@ -72,7 +76,11 @@ function ManualJournalActionsBar({
history.push('/make-journal-entry'); history.push('/make-journal-entry');
}; };
// Handle delete button click. // Handle delete button click.
const handleBulkDelete = () => { }; const handleBulkDelete = () => {
openAlert('journals-bulk-delete', {
journalsIds: manualJournalsSelectedRows,
});
};
// Handle tab change. // Handle tab change.
const handleTabChange = (view) => { const handleTabChange = (view) => {
@@ -200,6 +208,7 @@ function ManualJournalActionsBar({
export default compose( export default compose(
withDialogActions, withDialogActions,
withAlertActions,
withManualJournalsActions, withManualJournalsActions,
withSettingsActions, withSettingsActions,
withManualJournals(({ manualJournalsTableState, manualJournalsSelectedRows }) => ({ withManualJournals(({ manualJournalsTableState, manualJournalsSelectedRows }) => ({

View File

@@ -4,8 +4,8 @@ import { FormattedMessage as T } from '@/components';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core'; import { Intent, Alert } from '@blueprintjs/core';
import { queryCache } from 'react-query'; import { queryCache } from 'react-query';
import { AppToaster } from '@/components';
import { AppToaster } from '@/components';
import { useBulkDeleteInvoices } from '@/hooks/query/invoices'; import { useBulkDeleteInvoices } from '@/hooks/query/invoices';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect'; import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions'; import withAlertActions from '@/containers/Alert/withAlertActions';

View File

@@ -26,7 +26,6 @@ function PaymentReceivedBulkDeleteAlert({
const handleCancel = () => { const handleCancel = () => {
closeAlert(name); closeAlert(name);
}; };
const handleConfirmBulkDelete = () => { const handleConfirmBulkDelete = () => {
bulkDeletePaymentReceives(paymentsReceivedIds) bulkDeletePaymentReceives(paymentsReceivedIds)
.then(() => { .then(() => {

View File

@@ -34,6 +34,7 @@ import withExpensesActions from './withExpensesActions';
import withSettingsActions from '@/containers/Settings/withSettingsActions'; import withSettingsActions from '@/containers/Settings/withSettingsActions';
import withDialogActions from '@/containers/Dialog/withDialogActions'; import withDialogActions from '@/containers/Dialog/withDialogActions';
import withSettings from '@/containers/Settings/withSettings'; import withSettings from '@/containers/Settings/withSettings';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { compose } from '@/utils'; import { compose } from '@/utils';
import { isEmpty } from 'lodash'; import { isEmpty } from 'lodash';
@@ -47,7 +48,7 @@ function ExpensesActionsBar({
// #withExpenses // #withExpenses
expensesFilterConditions, expensesFilterConditions,
expensesSelectedRows, expensesSelectedRows = [],
// #withSettings // #withSettings
expensesTableSize, expensesTableSize,
@@ -57,6 +58,9 @@ function ExpensesActionsBar({
// #withDialogActions // #withDialogActions
openDialog, openDialog,
// #withAlertActions
openAlert,
}) { }) {
// History context. // History context.
const history = useHistory(); const history = useHistory();
@@ -75,7 +79,11 @@ function ExpensesActionsBar({
history.push('/expenses/new'); history.push('/expenses/new');
}; };
// Handle delete button click. // Handle delete button click.
const handleBulkDelete = () => { }; const handleBulkDelete = () => {
openAlert('expenses-bulk-delete', {
expensesIds: expensesSelectedRows,
});
};
// Handles the tab chaning. // Handles the tab chaning.
const handleTabChange = (view) => { const handleTabChange = (view) => {
@@ -113,6 +121,7 @@ function ExpensesActionsBar({
icon={<Icon icon="trash-16" iconSize={16} />} icon={<Icon icon="trash-16" iconSize={16} />}
text={<T id={'delete'} />} text={<T id={'delete'} />}
intent={Intent.DANGER} intent={Intent.DANGER}
onClick={handleBulkDelete}
/> />
</NavbarGroup> </NavbarGroup>
</DashboardActionsBar> </DashboardActionsBar>
@@ -200,6 +209,7 @@ function ExpensesActionsBar({
export default compose( export default compose(
withDialogActions, withDialogActions,
withAlertActions,
withExpensesActions, withExpensesActions,
withSettingsActions, withSettingsActions,
withExpenses(({ expensesTableState, expensesSelectedRows }) => ({ withExpenses(({ expensesTableState, expensesSelectedRows }) => ({

View File

@@ -3,12 +3,15 @@ import { connect } from 'react-redux';
import { import {
getVendorCreditTableStateFactory, getVendorCreditTableStateFactory,
isVendorCreditTableStateChangedFactory, isVendorCreditTableStateChangedFactory,
getVendorsCreditNoteSelectedRowsFactory,
} from '@/store/VendorCredit/vendorCredit.selector'; } from '@/store/VendorCredit/vendorCredit.selector';
export default (mapState) => { export default (mapState) => {
const getVendorsCreditNoteTableState = getVendorCreditTableStateFactoryth(); const getVendorsCreditNoteTableState = getVendorCreditTableStateFactory();
const isVendorsCreditNoteTableChanged = const isVendorsCreditNoteTableChanged =
isVendorCreditTableStateChangedFactory(); isVendorCreditTableStateChangedFactory();
const getVendorsCreditNoteSelectedRows =
getVendorsCreditNoteSelectedRowsFactory();
const mapStateToProps = (state, props) => { const mapStateToProps = (state, props) => {
const mapped = { const mapped = {

View File

@@ -13,7 +13,7 @@ import {
PopoverInteractionKind, PopoverInteractionKind,
Position, Position,
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import { isEmpty } from 'lodash';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import { import {
Icon, Icon,
@@ -27,6 +27,7 @@ import {
DashboardActionsBar, DashboardActionsBar,
} from '@/components'; } from '@/components';
import withAlertsActions from '@/containers/Alert/withAlertActions';
import withPaymentsReceived from './withPaymentsReceived'; import withPaymentsReceived from './withPaymentsReceived';
import withPaymentsReceivedActions from './withPaymentsReceivedActions'; import withPaymentsReceivedActions from './withPaymentsReceivedActions';
import withSettings from '@/containers/Settings/withSettings'; import withSettings from '@/containers/Settings/withSettings';
@@ -55,6 +56,7 @@ function PaymentsReceivedActionsBar({
// #withPaymentsReceived // #withPaymentsReceived
paymentFilterConditions, paymentFilterConditions,
paymentReceivesSelectedRows,
// #withSettings // #withSettings
paymentReceivesTableSize, paymentReceivesTableSize,
@@ -67,6 +69,9 @@ function PaymentsReceivedActionsBar({
// #withDrawerActions // #withDrawerActions
openDrawer, openDrawer,
// #withAlertsActions
openAlert,
}) { }) {
// History context. // History context.
const history = useHistory(); const history = useHistory();
@@ -89,12 +94,10 @@ function PaymentsReceivedActionsBar({
const handleTabChange = (viewId) => { const handleTabChange = (viewId) => {
setPaymentReceivesTableState({ customViewId: viewId.id || null }); setPaymentReceivesTableState({ customViewId: viewId.id || null });
}; };
// Handle click a refresh payment receives // Handle click a refresh payment receives
const handleRefreshBtnClick = () => { const handleRefreshBtnClick = () => {
refresh(); refresh();
}; };
// Handle table row size change. // Handle table row size change.
const handleTableRowSizeChange = (size) => { const handleTableRowSizeChange = (size) => {
addSetting('paymentReceives', 'tableSize', size); addSetting('paymentReceives', 'tableSize', size);
@@ -116,6 +119,24 @@ function PaymentsReceivedActionsBar({
openDrawer(DRAWERS.BRANDING_TEMPLATES, { resource: 'PaymentReceive' }); openDrawer(DRAWERS.BRANDING_TEMPLATES, { resource: 'PaymentReceive' });
}; };
if (!isEmpty(paymentReceivesSelectedRows)) {
const handleBulkDelete = () => {
openAlert('payments-received-bulk-delete', { paymentsReceivedIds: paymentReceivesSelectedRows });
};
return (
<DashboardActionsBar>
<NavbarGroup>
<Button
className={Classes.MINIMAL}
icon={<Icon icon="trash-16" iconSize={16} />}
text={<T id={'delete'} />}
intent={Intent.DANGER}
onClick={handleBulkDelete}
/>
</NavbarGroup>
</DashboardActionsBar>
);
}
return ( return (
<DashboardActionsBar> <DashboardActionsBar>
<NavbarGroup> <NavbarGroup>
@@ -147,16 +168,6 @@ function PaymentsReceivedActionsBar({
conditionsCount={paymentFilterConditions.length} conditionsCount={paymentFilterConditions.length}
/> />
</AdvancedFilterPopover> </AdvancedFilterPopover>
<If condition={false}>
<Button
className={Classes.MINIMAL}
icon={<Icon icon={'trash-16'} iconSize={16} />}
text={<T id={'delete'} />}
intent={Intent.DANGER}
// onClick={handleBulkDelete}
/>
</If>
<Button <Button
className={Classes.MINIMAL} className={Classes.MINIMAL}
icon={<Icon icon={'print-16'} iconSize={'16'} />} icon={<Icon icon={'print-16'} iconSize={'16'} />}
@@ -216,13 +227,15 @@ function PaymentsReceivedActionsBar({
export default compose( export default compose(
withPaymentsReceivedActions, withPaymentsReceivedActions,
withSettingsActions, withSettingsActions,
withPaymentsReceived(({ paymentReceivesTableState }) => ({ withPaymentsReceived(({ paymentReceivesTableState, paymentReceivesSelectedRows }) => ({
paymentReceivesTableState, paymentReceivesTableState,
paymentFilterConditions: paymentReceivesTableState.filterRoles, paymentFilterConditions: paymentReceivesTableState.filterRoles,
paymentReceivesSelectedRows,
})), })),
withSettings(({ paymentReceiveSettings }) => ({ withSettings(({ paymentReceiveSettings }) => ({
paymentReceivesTableSize: paymentReceiveSettings?.tableSize, paymentReceivesTableSize: paymentReceiveSettings?.tableSize,
})), })),
withDialogActions, withDialogActions,
withDrawerActions, withDrawerActions,
withAlertsActions,
)(PaymentsReceivedActionsBar); )(PaymentsReceivedActionsBar);

View File

@@ -32,6 +32,7 @@ import { DialogsName } from '@/constants/dialogs';
function PaymentsReceivedDataTable({ function PaymentsReceivedDataTable({
// #withPaymentsReceivedActions // #withPaymentsReceivedActions
setPaymentReceivesTableState, setPaymentReceivesTableState,
setPaymentReceivesSelectedRows,
// #withPaymentsReceived // #withPaymentsReceived
paymentReceivesTableState, paymentReceivesTableState,
@@ -106,6 +107,12 @@ function PaymentsReceivedDataTable({
[setPaymentReceivesTableState], [setPaymentReceivesTableState],
); );
// Handle selected rows change.
const handleSelectedRowsChange = (selectedRows) => {
const selectedIds = selectedRows?.map((row) => row.original.id) || [];
setPaymentReceivesSelectedRows(selectedIds);
};
// Display empty status instead of the table. // Display empty status instead of the table.
if (isEmptyStatus) { if (isEmptyStatus) {
return <PaymentReceivesEmptyStatus />; return <PaymentReceivesEmptyStatus />;
@@ -127,6 +134,7 @@ function PaymentsReceivedDataTable({
autoResetSortBy={false} autoResetSortBy={false}
autoResetPage={false} autoResetPage={false}
pagination={true} pagination={true}
onSelectedRowsChange={handleSelectedRowsChange}
initialPageSize={paymentReceivesTableState.pageSize} initialPageSize={paymentReceivesTableState.pageSize}
pagesCount={pagination.pagesCount} pagesCount={pagination.pagesCount}
TableLoadingRenderer={TableSkeletonRows} TableLoadingRenderer={TableSkeletonRows}

View File

@@ -2,17 +2,20 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { import {
getPaymentReceiveTableStateFactory, getPaymentReceiveTableStateFactory,
paymentsTableStateChangedFactory paymentsTableStateChangedFactory,
getPaymentReceivesSelectedRowsFactory
} from '@/store/PaymentReceives/paymentReceives.selector'; } from '@/store/PaymentReceives/paymentReceives.selector';
export default (mapState) => { export default (mapState) => {
const getPaymentReceiveTableState = getPaymentReceiveTableStateFactory(); const getPaymentReceiveTableState = getPaymentReceiveTableStateFactory();
const paymentsTableStateChanged = paymentsTableStateChangedFactory(); const paymentsTableStateChanged = paymentsTableStateChangedFactory();
const getSelectedRows = getPaymentReceivesSelectedRowsFactory();
const mapStateToProps = (state, props) => { const mapStateToProps = (state, props) => {
const mapped = { const mapped = {
paymentReceivesTableState: getPaymentReceiveTableState(state, props), paymentReceivesTableState: getPaymentReceiveTableState(state, props),
paymentsTableStateChanged: paymentsTableStateChanged(state, props), paymentsTableStateChanged: paymentsTableStateChanged(state, props),
paymentReceivesSelectedRows: getSelectedRows(state, props),
}; };
return mapState ? mapState(mapped, state, props) : mapped; return mapState ? mapState(mapped, state, props) : mapped;
}; };

View File

@@ -3,6 +3,7 @@ import { connect } from 'react-redux';
import { import {
setPaymentReceivesTableState, setPaymentReceivesTableState,
resetPaymentReceivesTableState, resetPaymentReceivesTableState,
setPaymentReceivesSelectedRows,
} from '@/store/PaymentReceives/paymentReceives.actions'; } from '@/store/PaymentReceives/paymentReceives.actions';
const mapDispatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({
@@ -11,6 +12,9 @@ const mapDispatchToProps = (dispatch) => ({
resetPaymentReceivesTableState: () => resetPaymentReceivesTableState: () =>
dispatch(resetPaymentReceivesTableState()), dispatch(resetPaymentReceivesTableState()),
setPaymentReceivesSelectedRows: (selectedRows: number[]) =>
dispatch(setPaymentReceivesSelectedRows(selectedRows)),
}); });
export default connect(null, mapDispatchToProps); export default connect(null, mapDispatchToProps);

View File

@@ -53,6 +53,7 @@ import { isEmpty } from 'lodash';
function ReceiptActionsBar({ function ReceiptActionsBar({
// #withReceiptsActions // #withReceiptsActions
setReceiptsTableState, setReceiptsTableState,
setReceiptsSelectedRows,
// #withReceipts // #withReceipts
receiptsFilterConditions, receiptsFilterConditions,
@@ -132,6 +133,7 @@ function ReceiptActionsBar({
icon={<Icon icon="trash-16" iconSize={16} />} icon={<Icon icon="trash-16" iconSize={16} />}
text={<T id={'delete'} />} text={<T id={'delete'} />}
intent={Intent.DANGER} intent={Intent.DANGER}
onClick={handleBulkDelete}
/> />
</NavbarGroup> </NavbarGroup>
</DashboardActionsBar> </DashboardActionsBar>

View File

@@ -32,6 +32,7 @@ import { DialogsName } from '@/constants/dialogs';
function ReceiptsDataTable({ function ReceiptsDataTable({
// #withReceiptsActions // #withReceiptsActions
setReceiptsTableState, setReceiptsTableState,
setReceiptsSelectedRows,
// #withReceipts // #withReceipts
receiptTableState, receiptTableState,
@@ -107,14 +108,19 @@ function ReceiptsDataTable({
}, },
[setReceiptsTableState], [setReceiptsTableState],
); );
if (isEmptyStatus) {
return <ReceiptsEmptyStatus />;
}
// Handle cell click. // Handle cell click.
const handleCellClick = (cell, event) => { const handleCellClick = (cell, event) => {
openDrawer(DRAWERS.RECEIPT_DETAILS, { receiptId: cell.row.original.id }); openDrawer(DRAWERS.RECEIPT_DETAILS, { receiptId: cell.row.original.id });
}; };
// Handle selected rows change.
const handleSelectedRowsChange = (selectedRows) => {
const selectedIds = selectedRows?.map((row) => row.original.id) || [];
setReceiptsSelectedRows(selectedIds);
};
if (isEmptyStatus) {
return <ReceiptsEmptyStatus />;
}
return ( return (
<DashboardContentTable> <DashboardContentTable>
@@ -142,6 +148,7 @@ function ReceiptsDataTable({
initialColumnsWidths={initialColumnsWidths} initialColumnsWidths={initialColumnsWidths}
onColumnResizing={handleColumnResizing} onColumnResizing={handleColumnResizing}
size={receiptsTableSize} size={receiptsTableSize}
onSelectedRowsChange={handleSelectedRowsChange}
payload={{ payload={{
onEdit: handleEditReceipt, onEdit: handleEditReceipt,
onDelete: handleDeleteReceipt, onDelete: handleDeleteReceipt,
@@ -160,9 +167,7 @@ export default compose(
withReceiptsActions, withReceiptsActions,
withDrawerActions, withDrawerActions,
withDialogActions, withDialogActions,
withReceipts(({ receiptTableState }) => ({ withReceipts(({ receiptTableState }) => ({ receiptTableState })),
receiptTableState,
})),
withSettings(({ receiptSettings }) => ({ withSettings(({ receiptSettings }) => ({
receiptsTableSize: receiptSettings?.tableSize, receiptsTableSize: receiptSettings?.tableSize,
})), })),

View File

@@ -3,11 +3,14 @@ import { connect } from 'react-redux';
import { import {
setReceiptsTableState, setReceiptsTableState,
resetReceiptsTableState, resetReceiptsTableState,
setReceiptsSelectedRows,
} from '@/store/receipts/receipts.actions'; } from '@/store/receipts/receipts.actions';
const mapDispatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({
setReceiptsTableState: (queries) => dispatch(setReceiptsTableState(queries)), setReceiptsTableState: (queries) => dispatch(setReceiptsTableState(queries)),
resetReceiptsTableState: () => dispatch(resetReceiptsTableState()), resetReceiptsTableState: () => dispatch(resetReceiptsTableState()),
setReceiptsSelectedRows: (selectedRows) =>
dispatch(setReceiptsSelectedRows(selectedRows)),
}); });
export default connect(null, mapDispatchToProps); export default connect(null, mapDispatchToProps);

View File

@@ -500,7 +500,9 @@
"the_estimate_has_been_edited_successfully": "The estimate #{number} has been edited successfully.", "the_estimate_has_been_edited_successfully": "The estimate #{number} has been edited successfully.",
"the_estimate_has_been_created_successfully": "The estimate #{number} has been created successfully.", "the_estimate_has_been_created_successfully": "The estimate #{number} has been created successfully.",
"the_estimate_has_been_deleted_successfully": "The estimate has been deleted successfully.", "the_estimate_has_been_deleted_successfully": "The estimate has been deleted successfully.",
"the_estimates_has_been_deleted_successfully": "The estimates have been deleted successfully.",
"once_delete_this_estimate_you_will_able_to_restore_it": "Once you delete this estimate, you won't be able to restore it later. Are you sure you want to delete it?", "once_delete_this_estimate_you_will_able_to_restore_it": "Once you delete this estimate, you won't be able to restore it later. Are you sure you want to delete it?",
"once_delete_these_estimates_you_will_not_able_restore_them": "Once you delete these estimates, you won't be able to retrieve them later. Are you sure you want to delete them?",
"cannot_be_zero_or_empty": "cannot be zero or empty.", "cannot_be_zero_or_empty": "cannot be zero or empty.",
"invoices": "Invoices", "invoices": "Invoices",
"invoices_list": "Invoices List", "invoices_list": "Invoices List",
@@ -522,7 +524,9 @@
"the_invoice_has_been_edited_successfully": "The invoice #{number} has been edited successfully.", "the_invoice_has_been_edited_successfully": "The invoice #{number} has been edited successfully.",
"the_invoice_has_been_created_successfully": "The invoice #{number} has been created successfully.", "the_invoice_has_been_created_successfully": "The invoice #{number} has been created successfully.",
"the_invoice_has_been_deleted_successfully": "The invoice has been deleted successfully.", "the_invoice_has_been_deleted_successfully": "The invoice has been deleted successfully.",
"the_invoices_has_been_deleted_successfully": "The invoices have been deleted successfully.",
"once_delete_this_invoice_you_will_able_to_restore_it": "Once you delete this invoice, you won't be able to restore it later. Are you sure you want to delete this invoice?", "once_delete_this_invoice_you_will_able_to_restore_it": "Once you delete this invoice, you won't be able to restore it later. Are you sure you want to delete this invoice?",
"once_delete_these_invoices_you_will_not_able_restore_them": "Once you delete these invoices, you won't be able to retrieve them later. Are you sure you want to delete them?",
"receipts_list": "Receipts List", "receipts_list": "Receipts List",
"receipts": "Receipts", "receipts": "Receipts",
"receipt": "Receipt #", "receipt": "Receipt #",
@@ -573,8 +577,10 @@
"receive_amount_": "Receive amount", "receive_amount_": "Receive amount",
"the_payment_received_transaction_has_been_created": "The payment received transaction has been created successfully.", "the_payment_received_transaction_has_been_created": "The payment received transaction has been created successfully.",
"the_payment_received_has_been_deleted_successfully": "The payment received has been deleted successfully.", "the_payment_received_has_been_deleted_successfully": "The payment received has been deleted successfully.",
"the_payments_received_has_been_deleted_successfully": "The payments received have been deleted successfully.",
"the_payment_received_transaction_has_been_edited": "The payment received transaction has been edited successfully.", "the_payment_received_transaction_has_been_edited": "The payment received transaction has been edited successfully.",
"once_delete_this_payment_received_you_will_able_to_restore_it": "Once you delete this payment received, you won't be able to restore it later. Are you sure you want to delete this payment transaction?", "once_delete_this_payment_received_you_will_able_to_restore_it": "Once you delete this payment received, you won't be able to restore it later. Are you sure you want to delete this payment transaction?",
"once_delete_these_payments_received_you_will_not_able_restore_them": "Once you delete these payments received, you won't be able to retrieve them later. Are you sure you want to delete them?",
"select_invoice": "Select Invoice", "select_invoice": "Select Invoice",
"payments_made": "Payments Made", "payments_made": "Payments Made",
"subscription": "Subscription", "subscription": "Subscription",

View File

@@ -2,26 +2,31 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { isEqual } from 'lodash'; import { isEqual } from 'lodash';
import { import { paginationLocationQuery } from '@/store/selectors';
paginationLocationQuery,
} from '@/store/selectors';
import { createDeepEqualSelector } from '@/utils'; import { createDeepEqualSelector } from '@/utils';
import { defaultTableQuery } from './paymentReceives.reducer'; import { defaultTableQuery } from './paymentReceives.reducer';
const paymentReceiveTableState = (state) => state.paymentReceives.tableState; const paymentReceiveTableState = (state) => state.paymentReceives.tableState;
// Retrieve payment receives table fetch query. // Retrieve payment receives table fetch query.
export const getPaymentReceiveTableStateFactory = () => createSelector( export const getPaymentReceiveTableStateFactory = () =>
paginationLocationQuery, createSelector(
paymentReceiveTableState, paginationLocationQuery,
(locationQuery, tableState) => { paymentReceiveTableState,
return { (locationQuery, tableState) => {
...locationQuery, return {
...tableState, ...locationQuery,
}; ...tableState,
}, };
); },
);
export const paymentsTableStateChangedFactory = () => export const paymentsTableStateChangedFactory = () =>
createDeepEqualSelector(paymentReceiveTableState, (tableState) => { createDeepEqualSelector(paymentReceiveTableState, (tableState) => {
return !isEqual(tableState, defaultTableQuery); return !isEqual(tableState, defaultTableQuery);
}); });
export const getPaymentReceivesSelectedRowsFactory = () =>
createSelector(
(state) => state.paymentReceives.selectedRows,
(selectedRows) => selectedRows,
);

View File

@@ -1,5 +1,6 @@
// @ts-nocheck // @ts-nocheck
import { isEqual } from 'lodash'; import { isEqual } from 'lodash';
import { createSelector } from 'reselect';
import { paginationLocationQuery } from '@/store/selectors'; import { paginationLocationQuery } from '@/store/selectors';
import { createDeepEqualSelector } from '@/utils'; import { createDeepEqualSelector } from '@/utils';
import { defaultTableQuery } from './VendorCredit.reducer'; import { defaultTableQuery } from './VendorCredit.reducer';

View File

@@ -13,3 +13,10 @@ export const resetReceiptsTableState = () => {
type: t.RECEIPTS_TABLE_STATE_RESET, type: t.RECEIPTS_TABLE_STATE_RESET,
}; };
} }
export const setReceiptsSelectedRows = (selectedRows) => {
return {
type: t.RECEIPTS_SELECTED_ROWS_SET,
payload: selectedRows,
};
};

View File

@@ -3,4 +3,5 @@
export default { export default {
RECEIPTS_TABLE_STATE_SET: 'RECEIPTS/TABLE_STATE_SET', RECEIPTS_TABLE_STATE_SET: 'RECEIPTS/TABLE_STATE_SET',
RECEIPTS_TABLE_STATE_RESET: 'RECEIPTS/TABLE_STATE_RESET', RECEIPTS_TABLE_STATE_RESET: 'RECEIPTS/TABLE_STATE_RESET',
RECEIPTS_SELECTED_ROWS_SET: 'RECEIPTS/SELECTED_ROWS_SET',
}; };