mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 04:40:32 +00:00
Merge pull request #958 from bigcapitalhq/premissions-guard
fix(server): permissions guard for read and write endpoints
This commit is contained in:
@@ -9,6 +9,7 @@ import {
|
||||
ParseIntPipe,
|
||||
Put,
|
||||
HttpCode,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { AccountsApplication } from './AccountsApplication.service';
|
||||
import { CreateAccountDTO } from './CreateAccount.dto';
|
||||
@@ -32,6 +33,11 @@ import {
|
||||
BulkDeleteDto,
|
||||
ValidateBulkDeleteResponseDto,
|
||||
} from '@/common/dtos/BulkDelete.dto';
|
||||
import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator';
|
||||
import { PermissionGuard } from '@/modules/Roles/Permission.guard';
|
||||
import { AuthorizationGuard } from '@/modules/Roles/Authorization.guard';
|
||||
import { AbilitySubject } from '@/modules/Roles/Roles.types';
|
||||
import { AccountAction } from './Accounts.types';
|
||||
|
||||
@Controller('accounts')
|
||||
@ApiTags('Accounts')
|
||||
@@ -40,11 +46,13 @@ import {
|
||||
@ApiExtraModels(GetAccountTransactionResponseDto)
|
||||
@ApiExtraModels(ValidateBulkDeleteResponseDto)
|
||||
@ApiCommonHeaders()
|
||||
@UseGuards(AuthorizationGuard, PermissionGuard)
|
||||
export class AccountsController {
|
||||
constructor(private readonly accountsApplication: AccountsApplication) { }
|
||||
|
||||
@Post('validate-bulk-delete')
|
||||
@HttpCode(200)
|
||||
@RequirePermission(AccountAction.DELETE, AbilitySubject.Account)
|
||||
@ApiOperation({
|
||||
summary:
|
||||
'Validates which accounts can be deleted and returns counts of deletable and non-deletable accounts.',
|
||||
@@ -67,6 +75,7 @@ export class AccountsController {
|
||||
|
||||
@Post('bulk-delete')
|
||||
@HttpCode(200)
|
||||
@RequirePermission(AccountAction.DELETE, AbilitySubject.Account)
|
||||
@ApiOperation({ summary: 'Deletes multiple accounts in bulk.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -81,6 +90,7 @@ export class AccountsController {
|
||||
}
|
||||
|
||||
@Post()
|
||||
@RequirePermission(AccountAction.CREATE, AbilitySubject.Account)
|
||||
@ApiOperation({ summary: 'Create an account' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -91,6 +101,7 @@ export class AccountsController {
|
||||
}
|
||||
|
||||
@Put(':id')
|
||||
@RequirePermission(AccountAction.EDIT, AbilitySubject.Account)
|
||||
@ApiOperation({ summary: 'Edit the given account.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -111,6 +122,7 @@ export class AccountsController {
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@RequirePermission(AccountAction.DELETE, AbilitySubject.Account)
|
||||
@ApiOperation({ summary: 'Delete the given account.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -129,6 +141,7 @@ export class AccountsController {
|
||||
|
||||
@Post(':id/activate')
|
||||
@HttpCode(200)
|
||||
@RequirePermission(AccountAction.EDIT, AbilitySubject.Account)
|
||||
@ApiOperation({ summary: 'Activate the given account.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -147,6 +160,7 @@ export class AccountsController {
|
||||
|
||||
@Post(':id/inactivate')
|
||||
@HttpCode(200)
|
||||
@RequirePermission(AccountAction.EDIT, AbilitySubject.Account)
|
||||
@ApiOperation({ summary: 'Inactivate the given account.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -164,6 +178,7 @@ export class AccountsController {
|
||||
}
|
||||
|
||||
@Get('types')
|
||||
@RequirePermission(AccountAction.VIEW, AbilitySubject.Account)
|
||||
@ApiOperation({ summary: 'Retrieves the account types.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -180,6 +195,7 @@ export class AccountsController {
|
||||
}
|
||||
|
||||
@Get('transactions')
|
||||
@RequirePermission(AccountAction.VIEW, AbilitySubject.Account)
|
||||
@ApiOperation({ summary: 'Retrieves the account transactions.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -198,6 +214,7 @@ export class AccountsController {
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@RequirePermission(AccountAction.VIEW, AbilitySubject.Account)
|
||||
@ApiOperation({ summary: 'Retrieves the account details.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -216,6 +233,7 @@ export class AccountsController {
|
||||
}
|
||||
|
||||
@Get()
|
||||
@RequirePermission(AccountAction.VIEW, AbilitySubject.Account)
|
||||
@ApiOperation({ summary: 'Retrieves the accounts.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
Post,
|
||||
Put,
|
||||
Query,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { BillPaymentsApplication } from './BillPaymentsApplication.service';
|
||||
import {
|
||||
@@ -26,12 +27,18 @@ import { BillPaymentsPages } from './commands/BillPaymentsPages.service';
|
||||
import { BillPaymentResponseDto } from './dtos/BillPaymentResponse.dto';
|
||||
import { PaginatedResponseDto } from '@/common/dtos/PaginatedResults.dto';
|
||||
import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders';
|
||||
import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator';
|
||||
import { PermissionGuard } from '@/modules/Roles/Permission.guard';
|
||||
import { AuthorizationGuard } from '@/modules/Roles/Authorization.guard';
|
||||
import { AbilitySubject } from '@/modules/Roles/Roles.types';
|
||||
import { IPaymentMadeAction } from './types/BillPayments.types';
|
||||
|
||||
@Controller('bill-payments')
|
||||
@ApiTags('Bill Payments')
|
||||
@ApiExtraModels(BillPaymentResponseDto)
|
||||
@ApiExtraModels(PaginatedResponseDto)
|
||||
@ApiCommonHeaders()
|
||||
@UseGuards(AuthorizationGuard, PermissionGuard)
|
||||
export class BillPaymentsController {
|
||||
constructor(
|
||||
private billPaymentsApplication: BillPaymentsApplication,
|
||||
@@ -39,12 +46,14 @@ export class BillPaymentsController {
|
||||
) {}
|
||||
|
||||
@Post()
|
||||
@RequirePermission(IPaymentMadeAction.Create, AbilitySubject.PaymentMade)
|
||||
@ApiOperation({ summary: 'Create a new bill payment.' })
|
||||
public createBillPayment(@Body() billPaymentDTO: CreateBillPaymentDto) {
|
||||
return this.billPaymentsApplication.createBillPayment(billPaymentDTO);
|
||||
}
|
||||
|
||||
@Delete(':billPaymentId')
|
||||
@RequirePermission(IPaymentMadeAction.Delete, AbilitySubject.PaymentMade)
|
||||
@ApiOperation({ summary: 'Delete the given bill payment.' })
|
||||
@ApiParam({
|
||||
name: 'billPaymentId',
|
||||
@@ -59,6 +68,7 @@ export class BillPaymentsController {
|
||||
}
|
||||
|
||||
@Put(':billPaymentId')
|
||||
@RequirePermission(IPaymentMadeAction.Edit, AbilitySubject.PaymentMade)
|
||||
@ApiOperation({ summary: 'Edit the given bill payment.' })
|
||||
@ApiParam({
|
||||
name: 'billPaymentId',
|
||||
@@ -77,6 +87,7 @@ export class BillPaymentsController {
|
||||
}
|
||||
|
||||
@Get('/new-page/entries')
|
||||
@RequirePermission(IPaymentMadeAction.View, AbilitySubject.PaymentMade)
|
||||
@ApiOperation({
|
||||
summary:
|
||||
'Retrieves the payable entries of the new page once vendor be selected.',
|
||||
@@ -95,6 +106,7 @@ export class BillPaymentsController {
|
||||
}
|
||||
|
||||
@Get(':billPaymentId/bills')
|
||||
@RequirePermission(IPaymentMadeAction.View, AbilitySubject.PaymentMade)
|
||||
@ApiOperation({ summary: 'Retrieves the bills of the given bill payment.' })
|
||||
@ApiParam({
|
||||
name: 'billPaymentId',
|
||||
@@ -107,6 +119,7 @@ export class BillPaymentsController {
|
||||
}
|
||||
|
||||
@Get('/:billPaymentId/edit-page')
|
||||
@RequirePermission(IPaymentMadeAction.View, AbilitySubject.PaymentMade)
|
||||
@ApiOperation({
|
||||
summary: 'Retrieves the edit page of the given bill payment.',
|
||||
})
|
||||
@@ -126,6 +139,7 @@ export class BillPaymentsController {
|
||||
}
|
||||
|
||||
@Get(':billPaymentId')
|
||||
@RequirePermission(IPaymentMadeAction.View, AbilitySubject.PaymentMade)
|
||||
@ApiOperation({ summary: 'Retrieves the bill payment details.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -145,6 +159,7 @@ export class BillPaymentsController {
|
||||
}
|
||||
|
||||
@Get()
|
||||
@RequirePermission(IPaymentMadeAction.View, AbilitySubject.PaymentMade)
|
||||
@ApiOperation({ summary: 'Retrieves the bill payments list.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
Get,
|
||||
Query,
|
||||
HttpCode,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { BillsApplication } from './Bills.application';
|
||||
import { IBillsFilter } from './Bills.types';
|
||||
@@ -28,6 +29,11 @@ import {
|
||||
BulkDeleteDto,
|
||||
ValidateBulkDeleteResponseDto,
|
||||
} from '@/common/dtos/BulkDelete.dto';
|
||||
import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator';
|
||||
import { PermissionGuard } from '@/modules/Roles/Permission.guard';
|
||||
import { AuthorizationGuard } from '@/modules/Roles/Authorization.guard';
|
||||
import { AbilitySubject } from '@/modules/Roles/Roles.types';
|
||||
import { BillAction } from './Bills.types';
|
||||
|
||||
@Controller('bills')
|
||||
@ApiTags('Bills')
|
||||
@@ -35,10 +41,12 @@ import {
|
||||
@ApiExtraModels(PaginatedResponseDto)
|
||||
@ApiCommonHeaders()
|
||||
@ApiExtraModels(ValidateBulkDeleteResponseDto)
|
||||
@UseGuards(AuthorizationGuard, PermissionGuard)
|
||||
export class BillsController {
|
||||
constructor(private billsApplication: BillsApplication) { }
|
||||
|
||||
@Post('validate-bulk-delete')
|
||||
@RequirePermission(BillAction.Delete, AbilitySubject.Bill)
|
||||
@ApiOperation({
|
||||
summary: 'Validate which bills can be deleted and return the results.',
|
||||
})
|
||||
@@ -58,6 +66,7 @@ export class BillsController {
|
||||
}
|
||||
|
||||
@Post('bulk-delete')
|
||||
@RequirePermission(BillAction.Delete, AbilitySubject.Bill)
|
||||
@ApiOperation({ summary: 'Deletes multiple bills.' })
|
||||
@HttpCode(200)
|
||||
@ApiResponse({
|
||||
@@ -73,12 +82,14 @@ export class BillsController {
|
||||
}
|
||||
|
||||
@Post()
|
||||
@RequirePermission(BillAction.Create, AbilitySubject.Bill)
|
||||
@ApiOperation({ summary: 'Create a new bill.' })
|
||||
createBill(@Body() billDTO: CreateBillDto) {
|
||||
return this.billsApplication.createBill(billDTO);
|
||||
}
|
||||
|
||||
@Put(':id')
|
||||
@RequirePermission(BillAction.Edit, AbilitySubject.Bill)
|
||||
@ApiOperation({ summary: 'Edit the given bill.' })
|
||||
@ApiParam({
|
||||
name: 'id',
|
||||
@@ -91,6 +102,7 @@ export class BillsController {
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@RequirePermission(BillAction.Delete, AbilitySubject.Bill)
|
||||
@ApiOperation({ summary: 'Delete the given bill.' })
|
||||
@ApiParam({
|
||||
name: 'id',
|
||||
@@ -103,6 +115,7 @@ export class BillsController {
|
||||
}
|
||||
|
||||
@Get()
|
||||
@RequirePermission(BillAction.View, AbilitySubject.Bill)
|
||||
@ApiOperation({ summary: 'Retrieves the bills.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -132,6 +145,7 @@ export class BillsController {
|
||||
}
|
||||
|
||||
@Get(':id/payment-transactions')
|
||||
@RequirePermission(BillAction.View, AbilitySubject.Bill)
|
||||
@ApiOperation({
|
||||
summary: 'Retrieve the specific bill associated payment transactions.',
|
||||
})
|
||||
@@ -146,6 +160,7 @@ export class BillsController {
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@RequirePermission(BillAction.View, AbilitySubject.Bill)
|
||||
@ApiOperation({ summary: 'Retrieves the bill details.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -165,6 +180,7 @@ export class BillsController {
|
||||
}
|
||||
|
||||
@Patch(':id/open')
|
||||
@RequirePermission(BillAction.Edit, AbilitySubject.Bill)
|
||||
@ApiOperation({ summary: 'Open the given bill.' })
|
||||
@ApiParam({
|
||||
name: 'id',
|
||||
@@ -177,6 +193,7 @@ export class BillsController {
|
||||
}
|
||||
|
||||
@Get('due')
|
||||
@RequirePermission(BillAction.View, AbilitySubject.Bill)
|
||||
@ApiOperation({ summary: 'Retrieves the due bills.' })
|
||||
getDueBills(@Body('vendorId') vendorId?: number) {
|
||||
return this.billsApplication.getDueBills(vendorId);
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
Put,
|
||||
Query,
|
||||
Res,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { CreditNoteApplication } from './CreditNoteApplication.service';
|
||||
import { ICreditNotesQueryDTO } from './types/CreditNotes.types';
|
||||
@@ -30,6 +31,11 @@ import {
|
||||
ValidateBulkDeleteResponseDto,
|
||||
} from '@/common/dtos/BulkDelete.dto';
|
||||
import { AcceptType } from '@/constants/accept-type';
|
||||
import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator';
|
||||
import { PermissionGuard } from '@/modules/Roles/Permission.guard';
|
||||
import { AuthorizationGuard } from '@/modules/Roles/Authorization.guard';
|
||||
import { AbilitySubject } from '@/modules/Roles/Roles.types';
|
||||
import { CreditNoteAction } from './types/CreditNotes.types';
|
||||
|
||||
@Controller('credit-notes')
|
||||
@ApiTags('Credit Notes')
|
||||
@@ -37,6 +43,7 @@ import { AcceptType } from '@/constants/accept-type';
|
||||
@ApiExtraModels(PaginatedResponseDto)
|
||||
@ApiExtraModels(ValidateBulkDeleteResponseDto)
|
||||
@ApiCommonHeaders()
|
||||
@UseGuards(AuthorizationGuard, PermissionGuard)
|
||||
export class CreditNotesController {
|
||||
/**
|
||||
* @param {CreditNoteApplication} creditNoteApplication - The credit note application service.
|
||||
@@ -44,6 +51,7 @@ export class CreditNotesController {
|
||||
constructor(private creditNoteApplication: CreditNoteApplication) { }
|
||||
|
||||
@Post()
|
||||
@RequirePermission(CreditNoteAction.Create, AbilitySubject.CreditNote)
|
||||
@ApiOperation({ summary: 'Create a new credit note' })
|
||||
@ApiResponse({ status: 201, description: 'Credit note successfully created' })
|
||||
@ApiResponse({ status: 400, description: 'Invalid input data' })
|
||||
@@ -52,6 +60,7 @@ export class CreditNotesController {
|
||||
}
|
||||
|
||||
@Get('state')
|
||||
@RequirePermission(CreditNoteAction.View, AbilitySubject.CreditNote)
|
||||
@ApiOperation({ summary: 'Get credit note state' })
|
||||
@ApiResponse({ status: 200, description: 'Returns the credit note state' })
|
||||
getCreditNoteState() {
|
||||
@@ -59,6 +68,7 @@ export class CreditNotesController {
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@RequirePermission(CreditNoteAction.View, AbilitySubject.CreditNote)
|
||||
@ApiOperation({ summary: 'Get a specific credit note by ID' })
|
||||
@ApiParam({ name: 'id', description: 'Credit note ID', type: 'number' })
|
||||
@ApiResponse({
|
||||
@@ -92,6 +102,7 @@ export class CreditNotesController {
|
||||
}
|
||||
|
||||
@Get()
|
||||
@RequirePermission(CreditNoteAction.View, AbilitySubject.CreditNote)
|
||||
@ApiOperation({ summary: 'Get all credit notes' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -115,6 +126,7 @@ export class CreditNotesController {
|
||||
}
|
||||
|
||||
@Put(':id')
|
||||
@RequirePermission(CreditNoteAction.Edit, AbilitySubject.CreditNote)
|
||||
@ApiOperation({ summary: 'Update a credit note' })
|
||||
@ApiParam({ name: 'id', description: 'Credit note ID', type: 'number' })
|
||||
@ApiResponse({ status: 200, description: 'Credit note successfully updated' })
|
||||
@@ -131,6 +143,7 @@ export class CreditNotesController {
|
||||
}
|
||||
|
||||
@Put(':id/open')
|
||||
@RequirePermission(CreditNoteAction.Edit, AbilitySubject.CreditNote)
|
||||
@ApiOperation({ summary: 'Open a credit note' })
|
||||
@ApiParam({ name: 'id', description: 'Credit note ID', type: 'number' })
|
||||
@ApiResponse({ status: 200, description: 'Credit note successfully opened' })
|
||||
@@ -140,6 +153,7 @@ export class CreditNotesController {
|
||||
}
|
||||
|
||||
@Post('validate-bulk-delete')
|
||||
@RequirePermission(CreditNoteAction.Delete, AbilitySubject.CreditNote)
|
||||
@ApiOperation({
|
||||
summary:
|
||||
'Validates which credit notes can be deleted and returns the results.',
|
||||
@@ -161,6 +175,7 @@ export class CreditNotesController {
|
||||
}
|
||||
|
||||
@Post('bulk-delete')
|
||||
@RequirePermission(CreditNoteAction.Delete, AbilitySubject.CreditNote)
|
||||
@ApiOperation({ summary: 'Deletes multiple credit notes.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -173,6 +188,7 @@ export class CreditNotesController {
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@RequirePermission(CreditNoteAction.Delete, AbilitySubject.CreditNote)
|
||||
@ApiOperation({ summary: 'Delete a credit note' })
|
||||
@ApiParam({ name: 'id', description: 'Credit note ID', type: 'number' })
|
||||
@ApiResponse({ status: 200, description: 'Credit note successfully deleted' })
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
Post,
|
||||
Put,
|
||||
Query,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { CustomersApplication } from './CustomersApplication.service';
|
||||
import { CustomerOpeningBalanceEditDto } from './dtos/CustomerOpeningBalanceEdit.dto';
|
||||
@@ -26,15 +27,22 @@ import {
|
||||
ValidateBulkDeleteCustomersResponseDto,
|
||||
} from './dtos/BulkDeleteCustomers.dto';
|
||||
import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders';
|
||||
import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator';
|
||||
import { PermissionGuard } from '@/modules/Roles/Permission.guard';
|
||||
import { AuthorizationGuard } from '@/modules/Roles/Authorization.guard';
|
||||
import { AbilitySubject } from '@/modules/Roles/Roles.types';
|
||||
import { CustomerAction } from './types/Customers.types';
|
||||
|
||||
@Controller('customers')
|
||||
@ApiTags('Customers')
|
||||
@ApiExtraModels(CustomerResponseDto)
|
||||
@ApiCommonHeaders()
|
||||
@UseGuards(AuthorizationGuard, PermissionGuard)
|
||||
export class CustomersController {
|
||||
constructor(private customersApplication: CustomersApplication) { }
|
||||
|
||||
@Get(':id')
|
||||
@RequirePermission(CustomerAction.View, AbilitySubject.Customer)
|
||||
@ApiOperation({ summary: 'Retrieves the customer details.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -46,6 +54,7 @@ export class CustomersController {
|
||||
}
|
||||
|
||||
@Get()
|
||||
@RequirePermission(CustomerAction.View, AbilitySubject.Customer)
|
||||
@ApiOperation({ summary: 'Retrieves the customers paginated list.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -60,6 +69,7 @@ export class CustomersController {
|
||||
}
|
||||
|
||||
@Post()
|
||||
@RequirePermission(CustomerAction.Create, AbilitySubject.Customer)
|
||||
@ApiOperation({ summary: 'Create a new customer.' })
|
||||
@ApiResponse({
|
||||
status: 201,
|
||||
@@ -71,6 +81,7 @@ export class CustomersController {
|
||||
}
|
||||
|
||||
@Put(':id')
|
||||
@RequirePermission(CustomerAction.Edit, AbilitySubject.Customer)
|
||||
@ApiOperation({ summary: 'Edit the given customer.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -85,6 +96,7 @@ export class CustomersController {
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@RequirePermission(CustomerAction.Delete, AbilitySubject.Customer)
|
||||
@ApiOperation({ summary: 'Delete the given customer.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -95,6 +107,7 @@ export class CustomersController {
|
||||
}
|
||||
|
||||
@Put(':id/opening-balance')
|
||||
@RequirePermission(CustomerAction.Edit, AbilitySubject.Customer)
|
||||
@ApiOperation({ summary: 'Edit the opening balance of the given customer.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -112,6 +125,7 @@ export class CustomersController {
|
||||
}
|
||||
|
||||
@Post('validate-bulk-delete')
|
||||
@RequirePermission(CustomerAction.Delete, AbilitySubject.Customer)
|
||||
@ApiOperation({
|
||||
summary:
|
||||
'Validates which customers can be deleted and returns counts of deletable and non-deletable customers.',
|
||||
@@ -131,6 +145,7 @@ export class CustomersController {
|
||||
}
|
||||
|
||||
@Post('bulk-delete')
|
||||
@RequirePermission(CustomerAction.Delete, AbilitySubject.Customer)
|
||||
@ApiOperation({ summary: 'Deletes multiple customers in bulk.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
Post,
|
||||
Put,
|
||||
Query,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { ExpensesApplication } from './ExpensesApplication.service';
|
||||
import { IExpensesFilter } from './Expenses.types';
|
||||
@@ -25,6 +26,11 @@ import {
|
||||
BulkDeleteDto,
|
||||
ValidateBulkDeleteResponseDto,
|
||||
} from '@/common/dtos/BulkDelete.dto';
|
||||
import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator';
|
||||
import { PermissionGuard } from '@/modules/Roles/Permission.guard';
|
||||
import { AuthorizationGuard } from '@/modules/Roles/Authorization.guard';
|
||||
import { AbilitySubject } from '@/modules/Roles/Roles.types';
|
||||
import { ExpenseAction } from './Expenses.types';
|
||||
|
||||
@Controller('expenses')
|
||||
@ApiTags('Expenses')
|
||||
@@ -34,10 +40,12 @@ import {
|
||||
ValidateBulkDeleteResponseDto,
|
||||
)
|
||||
@ApiCommonHeaders()
|
||||
@UseGuards(AuthorizationGuard, PermissionGuard)
|
||||
export class ExpensesController {
|
||||
constructor(private readonly expensesApplication: ExpensesApplication) { }
|
||||
|
||||
@Post('validate-bulk-delete')
|
||||
@RequirePermission(ExpenseAction.Delete, AbilitySubject.Expense)
|
||||
@ApiOperation({
|
||||
summary: 'Validate which expenses can be deleted and return the results.',
|
||||
})
|
||||
@@ -58,6 +66,7 @@ export class ExpensesController {
|
||||
}
|
||||
|
||||
@Post('bulk-delete')
|
||||
@RequirePermission(ExpenseAction.Delete, AbilitySubject.Expense)
|
||||
@ApiOperation({ summary: 'Deletes multiple expenses.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -76,6 +85,7 @@ export class ExpensesController {
|
||||
* @param {IExpenseCreateDTO} expenseDTO
|
||||
*/
|
||||
@Post()
|
||||
@RequirePermission(ExpenseAction.Create, AbilitySubject.Expense)
|
||||
@ApiOperation({ summary: 'Create a new expense transaction.' })
|
||||
public createExpense(@Body() expenseDTO: CreateExpenseDto) {
|
||||
return this.expensesApplication.createExpense(expenseDTO);
|
||||
@@ -87,6 +97,7 @@ export class ExpensesController {
|
||||
* @param {IExpenseEditDTO} expenseDTO
|
||||
*/
|
||||
@Put(':id')
|
||||
@RequirePermission(ExpenseAction.Edit, AbilitySubject.Expense)
|
||||
@ApiOperation({ summary: 'Edit the given expense transaction.' })
|
||||
public editExpense(
|
||||
@Param('id') expenseId: number,
|
||||
@@ -100,6 +111,7 @@ export class ExpensesController {
|
||||
* @param {number} expenseId
|
||||
*/
|
||||
@Delete(':id')
|
||||
@RequirePermission(ExpenseAction.Delete, AbilitySubject.Expense)
|
||||
@ApiOperation({ summary: 'Delete the given expense transaction.' })
|
||||
public deleteExpense(@Param('id') expenseId: number) {
|
||||
return this.expensesApplication.deleteExpense(expenseId);
|
||||
@@ -110,6 +122,7 @@ export class ExpensesController {
|
||||
* @param {number} expenseId
|
||||
*/
|
||||
@Post(':id/publish')
|
||||
@RequirePermission(ExpenseAction.Edit, AbilitySubject.Expense)
|
||||
@ApiOperation({ summary: 'Publish the given expense transaction.' })
|
||||
public publishExpense(@Param('id') expenseId: number) {
|
||||
return this.expensesApplication.publishExpense(expenseId);
|
||||
@@ -119,6 +132,7 @@ export class ExpensesController {
|
||||
* Get the expense transaction details.
|
||||
*/
|
||||
@Get()
|
||||
@RequirePermission(ExpenseAction.View, AbilitySubject.Expense)
|
||||
@ApiOperation({ summary: 'Get the expense transactions.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -146,6 +160,7 @@ export class ExpensesController {
|
||||
* @param {number} expenseId
|
||||
*/
|
||||
@Get(':id')
|
||||
@RequirePermission(ExpenseAction.View, AbilitySubject.Expense)
|
||||
@ApiOperation({ summary: 'Get the expense transaction details.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Response } from 'express';
|
||||
import { Controller, Get, Headers, Query, Res } from '@nestjs/common';
|
||||
import { Controller, Get, Headers, Query, Res, UseGuards } from '@nestjs/common';
|
||||
import { APAgingSummaryApplication } from './APAgingSummaryApplication';
|
||||
import { AcceptType } from '@/constants/accept-type';
|
||||
import {
|
||||
@@ -11,14 +11,21 @@ import {
|
||||
import { APAgingSummaryQueryDto } from './APAgingSummaryQuery.dto';
|
||||
import { APAgingSummaryResponseExample } from './APAgingSummary.swagger';
|
||||
import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders';
|
||||
import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator';
|
||||
import { PermissionGuard } from '@/modules/Roles/Permission.guard';
|
||||
import { AuthorizationGuard } from '@/modules/Roles/Authorization.guard';
|
||||
import { AbilitySubject } from '@/modules/Roles/Roles.types';
|
||||
import { ReportsAction } from '../../types/Report.types';
|
||||
|
||||
@Controller('reports/payable-aging-summary')
|
||||
@ApiTags('Reports')
|
||||
@ApiCommonHeaders()
|
||||
@UseGuards(AuthorizationGuard, PermissionGuard)
|
||||
export class APAgingSummaryController {
|
||||
constructor(private readonly APAgingSummaryApp: APAgingSummaryApplication) { }
|
||||
|
||||
@Get()
|
||||
@RequirePermission(ReportsAction.READ_AP_AGING_SUMMARY, AbilitySubject.Report)
|
||||
@ApiOperation({ summary: 'Get payable aging summary' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Controller, Get, Headers } from '@nestjs/common';
|
||||
import { Query, Res } from '@nestjs/common';
|
||||
import { Controller, Get, Headers, Query, Res, UseGuards } from '@nestjs/common';
|
||||
import { ARAgingSummaryApplication } from './ARAgingSummaryApplication';
|
||||
import { AcceptType } from '@/constants/accept-type';
|
||||
import { Response } from 'express';
|
||||
@@ -12,14 +11,21 @@ import {
|
||||
import { ARAgingSummaryQueryDto } from './ARAgingSummaryQuery.dto';
|
||||
import { ARAgingSummaryResponseExample } from './ARAgingSummary.swagger';
|
||||
import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders';
|
||||
import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator';
|
||||
import { PermissionGuard } from '@/modules/Roles/Permission.guard';
|
||||
import { AuthorizationGuard } from '@/modules/Roles/Authorization.guard';
|
||||
import { AbilitySubject } from '@/modules/Roles/Roles.types';
|
||||
import { ReportsAction } from '../../types/Report.types';
|
||||
|
||||
@Controller('reports/receivable-aging-summary')
|
||||
@ApiTags('Reports')
|
||||
@ApiCommonHeaders()
|
||||
@UseGuards(AuthorizationGuard, PermissionGuard)
|
||||
export class ARAgingSummaryController {
|
||||
constructor(private readonly ARAgingSummaryApp: ARAgingSummaryApplication) {}
|
||||
|
||||
@Get()
|
||||
@RequirePermission(ReportsAction.READ_AR_AGING_SUMMARY, AbilitySubject.Report)
|
||||
@ApiOperation({ summary: 'Get receivable aging summary' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Response } from 'express';
|
||||
import { Controller, Get, Headers, Query, Res } from '@nestjs/common';
|
||||
import { Controller, Get, Headers, Query, Res, UseGuards } from '@nestjs/common';
|
||||
import { AcceptType } from '@/constants/accept-type';
|
||||
import { BalanceSheetApplication } from './BalanceSheetApplication';
|
||||
import {
|
||||
@@ -11,10 +11,16 @@ import {
|
||||
import { BalanceSheetQueryDto } from './BalanceSheet.dto';
|
||||
import { BalanceSheetResponseExample } from './BalanceSheet.swagger';
|
||||
import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders';
|
||||
import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator';
|
||||
import { PermissionGuard } from '@/modules/Roles/Permission.guard';
|
||||
import { AuthorizationGuard } from '@/modules/Roles/Authorization.guard';
|
||||
import { AbilitySubject } from '@/modules/Roles/Roles.types';
|
||||
import { ReportsAction } from '../../types/Report.types';
|
||||
|
||||
@Controller('/reports/balance-sheet')
|
||||
@ApiTags('Reports')
|
||||
@ApiCommonHeaders()
|
||||
@UseGuards(AuthorizationGuard, PermissionGuard)
|
||||
export class BalanceSheetStatementController {
|
||||
constructor(private readonly balanceSheetApp: BalanceSheetApplication) {}
|
||||
|
||||
@@ -25,6 +31,7 @@ export class BalanceSheetStatementController {
|
||||
* @param {string} acceptHeader - Accept header.
|
||||
*/
|
||||
@Get('')
|
||||
@RequirePermission(ReportsAction.READ_BALANCE_SHEET, AbilitySubject.Report)
|
||||
@ApiOperation({ summary: 'Get balance sheet statement' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Response } from 'express';
|
||||
import { Controller, Get, Headers, Query, Res } from '@nestjs/common';
|
||||
import { Controller, Get, Headers, Query, Res, UseGuards } from '@nestjs/common';
|
||||
import { AcceptType } from '@/constants/accept-type';
|
||||
import { CashflowSheetApplication } from './CashflowSheetApplication';
|
||||
import {
|
||||
@@ -11,14 +11,21 @@ import {
|
||||
import { CashFlowStatementQueryDto } from './CashFlowStatementQuery.dto';
|
||||
import { CashflowStatementResponseExample } from './CashflowStatement.swagger';
|
||||
import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders';
|
||||
import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator';
|
||||
import { PermissionGuard } from '@/modules/Roles/Permission.guard';
|
||||
import { AuthorizationGuard } from '@/modules/Roles/Authorization.guard';
|
||||
import { AbilitySubject } from '@/modules/Roles/Roles.types';
|
||||
import { ReportsAction } from '../../types/Report.types';
|
||||
|
||||
@Controller('reports/cashflow-statement')
|
||||
@ApiTags('Reports')
|
||||
@ApiCommonHeaders()
|
||||
@UseGuards(AuthorizationGuard, PermissionGuard)
|
||||
export class CashflowController {
|
||||
constructor(private readonly cashflowSheetApp: CashflowSheetApplication) { }
|
||||
|
||||
@Get()
|
||||
@RequirePermission(ReportsAction.READ_CASHFLOW, AbilitySubject.Report)
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Cashflow statement report',
|
||||
|
||||
@@ -5,22 +5,29 @@ import {
|
||||
ApiTags,
|
||||
} from '@nestjs/swagger';
|
||||
import { Response } from 'express';
|
||||
import { Controller, Get, Headers, Query, Res } from '@nestjs/common';
|
||||
import { Controller, Get, Headers, Query, Res, UseGuards } from '@nestjs/common';
|
||||
import { GeneralLedgerApplication } from './GeneralLedgerApplication';
|
||||
import { AcceptType } from '@/constants/accept-type';
|
||||
import { GeneralLedgerQueryDto } from './GeneralLedgerQuery.dto';
|
||||
import { GeneralLedgerResponseExample } from './GeneralLedger.swagger';
|
||||
import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders';
|
||||
import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator';
|
||||
import { PermissionGuard } from '@/modules/Roles/Permission.guard';
|
||||
import { AuthorizationGuard } from '@/modules/Roles/Authorization.guard';
|
||||
import { AbilitySubject } from '@/modules/Roles/Roles.types';
|
||||
import { ReportsAction } from '../../types/Report.types';
|
||||
|
||||
@Controller('/reports/general-ledger')
|
||||
@ApiTags('Reports')
|
||||
@ApiCommonHeaders()
|
||||
@UseGuards(AuthorizationGuard, PermissionGuard)
|
||||
export class GeneralLedgerController {
|
||||
constructor(
|
||||
private readonly generalLedgerApplication: GeneralLedgerApplication,
|
||||
) {}
|
||||
|
||||
@Get()
|
||||
@RequirePermission(ReportsAction.READ_GENERAL_LEDGET, AbilitySubject.Report)
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'General ledger report',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Controller, Get, Headers, Query, Res } from '@nestjs/common';
|
||||
import { Controller, Get, Headers, Query, Res, UseGuards } from '@nestjs/common';
|
||||
import { Response } from 'express';
|
||||
import { AcceptType } from '@/constants/accept-type';
|
||||
import { JournalSheetApplication } from './JournalSheetApplication';
|
||||
@@ -11,14 +11,21 @@ import {
|
||||
import { JournalSheetQueryDto } from './JournalSheetQuery.dto';
|
||||
import { JournalSheetResponseExample } from './JournalSheet.swagger';
|
||||
import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders';
|
||||
import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator';
|
||||
import { PermissionGuard } from '@/modules/Roles/Permission.guard';
|
||||
import { AuthorizationGuard } from '@/modules/Roles/Authorization.guard';
|
||||
import { AbilitySubject } from '@/modules/Roles/Roles.types';
|
||||
import { ReportsAction } from '../../types/Report.types';
|
||||
|
||||
@Controller('/reports/journal')
|
||||
@ApiTags('Reports')
|
||||
@ApiCommonHeaders()
|
||||
@UseGuards(AuthorizationGuard, PermissionGuard)
|
||||
export class JournalSheetController {
|
||||
constructor(private readonly journalSheetApp: JournalSheetApplication) {}
|
||||
|
||||
@Get()
|
||||
@RequirePermission(ReportsAction.READ_JOURNAL, AbilitySubject.Report)
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Journal report',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Response } from 'express';
|
||||
import { Controller, Get, Headers, Query, Res } from '@nestjs/common';
|
||||
import { Controller, Get, Headers, Query, Res, UseGuards } from '@nestjs/common';
|
||||
import { ProfitLossSheetApplication } from './ProfitLossSheetApplication';
|
||||
import { AcceptType } from '@/constants/accept-type';
|
||||
import {
|
||||
@@ -11,10 +11,16 @@ import {
|
||||
import { ProfitLossSheetQueryDto } from './ProfitLossSheetQuery.dto';
|
||||
import { ProfitLossSheetResponseExample } from './ProfitLossSheet.swagger';
|
||||
import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders';
|
||||
import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator';
|
||||
import { PermissionGuard } from '@/modules/Roles/Permission.guard';
|
||||
import { AuthorizationGuard } from '@/modules/Roles/Authorization.guard';
|
||||
import { AbilitySubject } from '@/modules/Roles/Roles.types';
|
||||
import { ReportsAction } from '../../types/Report.types';
|
||||
|
||||
@Controller('/reports/profit-loss-sheet')
|
||||
@ApiTags('Reports')
|
||||
@ApiCommonHeaders()
|
||||
@UseGuards(AuthorizationGuard, PermissionGuard)
|
||||
export class ProfitLossSheetController {
|
||||
constructor(
|
||||
private readonly profitLossSheetApp: ProfitLossSheetApplication,
|
||||
@@ -27,6 +33,7 @@ export class ProfitLossSheetController {
|
||||
* @param {string} acceptHeader
|
||||
*/
|
||||
@Get('/')
|
||||
@RequirePermission(ReportsAction.READ_PROFIT_LOSS, AbilitySubject.Report)
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Profit & loss statement',
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
Post,
|
||||
Put,
|
||||
Query,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { InventoryAdjustmentsApplicationService } from './InventoryAdjustmentsApplication.service';
|
||||
import { IInventoryAdjustmentsFilter } from './types/InventoryAdjustments.types';
|
||||
@@ -21,17 +22,24 @@ import { InventoryAdjustment } from './models/InventoryAdjustment';
|
||||
import { CreateQuickInventoryAdjustmentDto } from './dtos/CreateQuickInventoryAdjustment.dto';
|
||||
import { InventoryAdjustmentResponseDto } from './dtos/InventoryAdjustmentResponse.dto';
|
||||
import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders';
|
||||
import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator';
|
||||
import { PermissionGuard } from '@/modules/Roles/Permission.guard';
|
||||
import { AuthorizationGuard } from '@/modules/Roles/Authorization.guard';
|
||||
import { AbilitySubject } from '@/modules/Roles/Roles.types';
|
||||
import { InventoryAdjustmentAction } from './types/InventoryAdjustments.types';
|
||||
|
||||
@Controller('inventory-adjustments')
|
||||
@ApiTags('Inventory Adjustments')
|
||||
@ApiExtraModels(InventoryAdjustmentResponseDto)
|
||||
@ApiCommonHeaders()
|
||||
@UseGuards(AuthorizationGuard, PermissionGuard)
|
||||
export class InventoryAdjustmentsController {
|
||||
constructor(
|
||||
private readonly inventoryAdjustmentsApplicationService: InventoryAdjustmentsApplicationService,
|
||||
) {}
|
||||
|
||||
@Post('quick')
|
||||
@RequirePermission(InventoryAdjustmentAction.CREATE, AbilitySubject.InventoryAdjustment)
|
||||
@ApiOperation({ summary: 'Create a quick inventory adjustment.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -46,6 +54,7 @@ export class InventoryAdjustmentsController {
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@RequirePermission(InventoryAdjustmentAction.DELETE, AbilitySubject.InventoryAdjustment)
|
||||
@ApiOperation({ summary: 'Delete the given inventory adjustment.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -60,6 +69,7 @@ export class InventoryAdjustmentsController {
|
||||
}
|
||||
|
||||
@Get()
|
||||
@RequirePermission(InventoryAdjustmentAction.VIEW, AbilitySubject.InventoryAdjustment)
|
||||
@ApiOperation({ summary: 'Retrieves the inventory adjustments.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -78,6 +88,7 @@ export class InventoryAdjustmentsController {
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@RequirePermission(InventoryAdjustmentAction.VIEW, AbilitySubject.InventoryAdjustment)
|
||||
@ApiOperation({ summary: 'Retrieves the inventory adjustment details.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -94,6 +105,7 @@ export class InventoryAdjustmentsController {
|
||||
}
|
||||
|
||||
@Put(':id/publish')
|
||||
@RequirePermission(InventoryAdjustmentAction.EDIT, AbilitySubject.InventoryAdjustment)
|
||||
@ApiOperation({ summary: 'Publish the given inventory adjustment.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
Put,
|
||||
Query,
|
||||
HttpCode,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { TenantController } from '../Tenancy/Tenant.controller';
|
||||
import { ItemsApplicationService } from './ItemsApplication.service';
|
||||
@@ -35,6 +36,11 @@ import {
|
||||
ValidateBulkDeleteItemsResponseDto,
|
||||
} from './dtos/BulkDeleteItems.dto';
|
||||
import { ItemApiErrorResponseDto } from './dtos/ItemErrorResponse.dto';
|
||||
import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator';
|
||||
import { PermissionGuard } from '@/modules/Roles/Permission.guard';
|
||||
import { AuthorizationGuard } from '@/modules/Roles/Authorization.guard';
|
||||
import { AbilitySubject } from '@/modules/Roles/Roles.types';
|
||||
import { ItemAction } from '@/interfaces/Item';
|
||||
|
||||
@Controller('/items')
|
||||
@ApiTags('Items')
|
||||
@@ -48,12 +54,14 @@ import { ItemApiErrorResponseDto } from './dtos/ItemErrorResponse.dto';
|
||||
@ApiExtraModels(ValidateBulkDeleteItemsResponseDto)
|
||||
@ApiExtraModels(ItemApiErrorResponseDto)
|
||||
@ApiCommonHeaders()
|
||||
@UseGuards(AuthorizationGuard, PermissionGuard)
|
||||
export class ItemsController extends TenantController {
|
||||
constructor(private readonly itemsApplication: ItemsApplicationService) {
|
||||
super();
|
||||
}
|
||||
|
||||
@Get()
|
||||
@RequirePermission(ItemAction.VIEW, AbilitySubject.Item)
|
||||
@ApiOperation({ summary: 'Retrieves the item list.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -144,6 +152,7 @@ export class ItemsController extends TenantController {
|
||||
* @returns The updated item id.
|
||||
*/
|
||||
@Put(':id')
|
||||
@RequirePermission(ItemAction.EDIT, AbilitySubject.Item)
|
||||
@ApiOperation({ summary: 'Edit the given item (product or service).' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -174,6 +183,7 @@ export class ItemsController extends TenantController {
|
||||
|
||||
@Post('validate-bulk-delete')
|
||||
@HttpCode(200)
|
||||
@RequirePermission(ItemAction.DELETE, AbilitySubject.Item)
|
||||
@ApiOperation({
|
||||
summary:
|
||||
'Validates which items can be deleted and returns counts of deletable and non-deletable items.',
|
||||
@@ -194,6 +204,7 @@ export class ItemsController extends TenantController {
|
||||
|
||||
@Post('bulk-delete')
|
||||
@HttpCode(200)
|
||||
@RequirePermission(ItemAction.DELETE, AbilitySubject.Item)
|
||||
@ApiOperation({ summary: 'Deletes multiple items in bulk.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -208,6 +219,7 @@ export class ItemsController extends TenantController {
|
||||
}
|
||||
|
||||
@Post()
|
||||
@RequirePermission(ItemAction.CREATE, AbilitySubject.Item)
|
||||
@ApiOperation({ summary: 'Create a new item (product or service).' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -230,6 +242,7 @@ export class ItemsController extends TenantController {
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@RequirePermission(ItemAction.DELETE, AbilitySubject.Item)
|
||||
@ApiOperation({ summary: 'Delete the given item (product or service).' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -255,6 +268,7 @@ export class ItemsController extends TenantController {
|
||||
}
|
||||
|
||||
@Patch(':id/inactivate')
|
||||
@RequirePermission(ItemAction.EDIT, AbilitySubject.Item)
|
||||
@ApiOperation({ summary: 'Inactivate the given item (product or service).' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -273,6 +287,7 @@ export class ItemsController extends TenantController {
|
||||
}
|
||||
|
||||
@Patch(':id/activate')
|
||||
@RequirePermission(ItemAction.EDIT, AbilitySubject.Item)
|
||||
@ApiOperation({ summary: 'Activate the given item (product or service).' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -291,6 +306,7 @@ export class ItemsController extends TenantController {
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@RequirePermission(ItemAction.VIEW, AbilitySubject.Item)
|
||||
@ApiOperation({ summary: 'Get the given item (product or service).' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -312,6 +328,7 @@ export class ItemsController extends TenantController {
|
||||
}
|
||||
|
||||
@Get(':id/invoices')
|
||||
@RequirePermission(ItemAction.VIEW, AbilitySubject.Item)
|
||||
@ApiOperation({
|
||||
summary: 'Retrieves the item associated invoices transactions.',
|
||||
})
|
||||
@@ -337,6 +354,7 @@ export class ItemsController extends TenantController {
|
||||
}
|
||||
|
||||
@Get(':id/bills')
|
||||
@RequirePermission(ItemAction.VIEW, AbilitySubject.Item)
|
||||
@ApiOperation({
|
||||
summary: 'Retrieves the item associated bills transactions.',
|
||||
})
|
||||
@@ -362,6 +380,7 @@ export class ItemsController extends TenantController {
|
||||
}
|
||||
|
||||
@Get(':id/estimates')
|
||||
@RequirePermission(ItemAction.VIEW, AbilitySubject.Item)
|
||||
@ApiOperation({
|
||||
summary: 'Retrieves the item associated estimates transactions.',
|
||||
})
|
||||
@@ -387,6 +406,7 @@ export class ItemsController extends TenantController {
|
||||
}
|
||||
|
||||
@Get(':id/receipts')
|
||||
@RequirePermission(ItemAction.VIEW, AbilitySubject.Item)
|
||||
@ApiOperation({
|
||||
summary: 'Retrieves the item associated receipts transactions.',
|
||||
})
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
Post,
|
||||
Put,
|
||||
Query,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { ManualJournalsApplication } from './ManualJournalsApplication.service';
|
||||
import {
|
||||
@@ -29,16 +30,23 @@ import {
|
||||
BulkDeleteDto,
|
||||
ValidateBulkDeleteResponseDto,
|
||||
} from '@/common/dtos/BulkDelete.dto';
|
||||
import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator';
|
||||
import { PermissionGuard } from '@/modules/Roles/Permission.guard';
|
||||
import { AuthorizationGuard } from '@/modules/Roles/Authorization.guard';
|
||||
import { AbilitySubject } from '@/modules/Roles/Roles.types';
|
||||
import { ManualJournalAction } from './types/ManualJournals.types';
|
||||
|
||||
@Controller('manual-journals')
|
||||
@ApiTags('Manual Journals')
|
||||
@ApiExtraModels(ManualJournalResponseDto)
|
||||
@ApiExtraModels(ValidateBulkDeleteResponseDto)
|
||||
@ApiCommonHeaders()
|
||||
@UseGuards(AuthorizationGuard, PermissionGuard)
|
||||
export class ManualJournalsController {
|
||||
constructor(private manualJournalsApplication: ManualJournalsApplication) { }
|
||||
|
||||
@Post('validate-bulk-delete')
|
||||
@RequirePermission(ManualJournalAction.Delete, AbilitySubject.ManualJournal)
|
||||
@ApiOperation({
|
||||
summary:
|
||||
'Validate which manual journals can be deleted and return the results.',
|
||||
@@ -60,6 +68,7 @@ export class ManualJournalsController {
|
||||
}
|
||||
|
||||
@Post('bulk-delete')
|
||||
@RequirePermission(ManualJournalAction.Delete, AbilitySubject.ManualJournal)
|
||||
@ApiOperation({ summary: 'Deletes multiple manual journals.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -75,6 +84,7 @@ export class ManualJournalsController {
|
||||
}
|
||||
|
||||
@Post()
|
||||
@RequirePermission(ManualJournalAction.Create, AbilitySubject.ManualJournal)
|
||||
@ApiOperation({ summary: 'Create a new manual journal.' })
|
||||
@ApiResponse({
|
||||
status: 201,
|
||||
@@ -86,6 +96,7 @@ export class ManualJournalsController {
|
||||
}
|
||||
|
||||
@Put(':id')
|
||||
@RequirePermission(ManualJournalAction.Edit, AbilitySubject.ManualJournal)
|
||||
@ApiOperation({ summary: 'Edit the given manual journal.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -110,6 +121,7 @@ export class ManualJournalsController {
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@RequirePermission(ManualJournalAction.Delete, AbilitySubject.ManualJournal)
|
||||
@ApiOperation({ summary: 'Delete the given manual journal.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -127,6 +139,7 @@ export class ManualJournalsController {
|
||||
}
|
||||
|
||||
@Patch(':id/publish')
|
||||
@RequirePermission(ManualJournalAction.Edit, AbilitySubject.ManualJournal)
|
||||
@ApiOperation({ summary: 'Publish the given manual journal.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -147,6 +160,7 @@ export class ManualJournalsController {
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@RequirePermission(ManualJournalAction.View, AbilitySubject.ManualJournal)
|
||||
@ApiOperation({ summary: 'Retrieves the manual journal details.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -167,6 +181,7 @@ export class ManualJournalsController {
|
||||
}
|
||||
|
||||
@Get()
|
||||
@RequirePermission(ManualJournalAction.View, AbilitySubject.ManualJournal)
|
||||
@ApiOperation({ summary: 'Retrieves the manual journals paginated list.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
Put,
|
||||
Query,
|
||||
Res,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { PaymentReceivesApplication } from './PaymentReceived.application';
|
||||
import {
|
||||
@@ -38,6 +39,11 @@ import {
|
||||
BulkDeleteDto,
|
||||
ValidateBulkDeleteResponseDto,
|
||||
} from '@/common/dtos/BulkDelete.dto';
|
||||
import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator';
|
||||
import { PermissionGuard } from '@/modules/Roles/Permission.guard';
|
||||
import { AuthorizationGuard } from '@/modules/Roles/Authorization.guard';
|
||||
import { AbilitySubject } from '@/modules/Roles/Roles.types';
|
||||
import { PaymentReceiveAction } from './types/PaymentReceived.types';
|
||||
|
||||
@Controller('payments-received')
|
||||
@ApiTags('Payments Received')
|
||||
@@ -46,6 +52,7 @@ import {
|
||||
@ApiExtraModels(PaymentReceivedStateResponseDto)
|
||||
@ApiExtraModels(ValidateBulkDeleteResponseDto)
|
||||
@ApiCommonHeaders()
|
||||
@UseGuards(AuthorizationGuard, PermissionGuard)
|
||||
export class PaymentReceivesController {
|
||||
constructor(private paymentReceivesApplication: PaymentReceivesApplication) { }
|
||||
|
||||
@@ -94,6 +101,7 @@ export class PaymentReceivesController {
|
||||
}
|
||||
|
||||
@Post()
|
||||
@RequirePermission(PaymentReceiveAction.Create, AbilitySubject.PaymentReceive)
|
||||
@ApiOperation({ summary: 'Create a new payment received.' })
|
||||
public createPaymentReceived(
|
||||
@Body() paymentReceiveDTO: CreatePaymentReceivedDto,
|
||||
@@ -104,6 +112,7 @@ export class PaymentReceivesController {
|
||||
}
|
||||
|
||||
@Put(':id')
|
||||
@RequirePermission(PaymentReceiveAction.Edit, AbilitySubject.PaymentReceive)
|
||||
@ApiOperation({ summary: 'Edit the given payment received.' })
|
||||
public editPaymentReceive(
|
||||
@Param('id', ParseIntPipe) paymentReceiveId: number,
|
||||
@@ -116,6 +125,7 @@ export class PaymentReceivesController {
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@RequirePermission(PaymentReceiveAction.Delete, AbilitySubject.PaymentReceive)
|
||||
@ApiOperation({ summary: 'Delete the given payment received.' })
|
||||
public deletePaymentReceive(
|
||||
@Param('id', ParseIntPipe) paymentReceiveId: number,
|
||||
@@ -126,6 +136,7 @@ export class PaymentReceivesController {
|
||||
}
|
||||
|
||||
@Get()
|
||||
@RequirePermission(PaymentReceiveAction.View, AbilitySubject.PaymentReceive)
|
||||
@ApiOperation({ summary: 'Retrieves the payment received list.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -151,6 +162,7 @@ export class PaymentReceivesController {
|
||||
}
|
||||
|
||||
@Post('validate-bulk-delete')
|
||||
@RequirePermission(PaymentReceiveAction.Delete, AbilitySubject.PaymentReceive)
|
||||
@ApiOperation({
|
||||
summary:
|
||||
'Validates which payments received can be deleted and returns the results.',
|
||||
@@ -172,6 +184,7 @@ export class PaymentReceivesController {
|
||||
}
|
||||
|
||||
@Post('bulk-delete')
|
||||
@RequirePermission(PaymentReceiveAction.Delete, AbilitySubject.PaymentReceive)
|
||||
@ApiOperation({ summary: 'Deletes multiple payments received.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -187,6 +200,7 @@ export class PaymentReceivesController {
|
||||
}
|
||||
|
||||
@Get('state')
|
||||
@RequirePermission(PaymentReceiveAction.View, AbilitySubject.PaymentReceive)
|
||||
@ApiOperation({ summary: 'Retrieves the payment received state.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -200,6 +214,7 @@ export class PaymentReceivesController {
|
||||
}
|
||||
|
||||
@Get(':id/invoices')
|
||||
@RequirePermission(PaymentReceiveAction.View, AbilitySubject.PaymentReceive)
|
||||
@ApiOperation({ summary: 'Retrieves the payment received invoices.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -215,6 +230,7 @@ export class PaymentReceivesController {
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@RequirePermission(PaymentReceiveAction.View, AbilitySubject.PaymentReceive)
|
||||
@ApiOperation({ summary: 'Retrieves the payment received details.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
|
||||
67
packages/server/src/modules/Roles/Permission.guard.ts
Normal file
67
packages/server/src/modules/Roles/Permission.guard.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import {
|
||||
Injectable,
|
||||
CanActivate,
|
||||
ExecutionContext,
|
||||
ForbiddenException,
|
||||
} from '@nestjs/common';
|
||||
import { Reflector } from '@nestjs/core';
|
||||
import { Request } from 'express';
|
||||
import { REQUIRED_PERMISSION_KEY, RequiredPermission } from './RequirePermission.decorator';
|
||||
import { AbilitySubject } from './Roles.types';
|
||||
|
||||
/**
|
||||
* Guard that checks if the user has the required permission to access a route.
|
||||
* Uses CASL ability instance attached to the request by AuthorizationGuard.
|
||||
*/
|
||||
@Injectable()
|
||||
export class PermissionGuard implements CanActivate {
|
||||
constructor(private readonly reflector: Reflector) {}
|
||||
|
||||
/**
|
||||
* Checks if the user has the required permission to access the route.
|
||||
* @param context - The execution context
|
||||
* @returns A boolean indicating if the user can access the route
|
||||
* @throws ForbiddenException if the user doesn't have the required permission
|
||||
*/
|
||||
canActivate(context: ExecutionContext): boolean {
|
||||
const requiredPermission = this.reflector.getAllAndOverride<RequiredPermission>(
|
||||
REQUIRED_PERMISSION_KEY,
|
||||
[context.getHandler(), context.getClass()],
|
||||
);
|
||||
|
||||
// If no permission is required, allow access
|
||||
if (!requiredPermission) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const request = context.switchToHttp().getRequest<Request>();
|
||||
const ability = (request as any).ability;
|
||||
|
||||
// If no ability instance is attached to the request, deny access
|
||||
if (!ability) {
|
||||
throw new ForbiddenException('Ability instance not found. Ensure AuthorizationGuard is applied.');
|
||||
}
|
||||
|
||||
const { ability: action, subject } = requiredPermission;
|
||||
|
||||
// Check if the user has the required permission using CASL ability
|
||||
const hasPermission = ability.can(action, subject);
|
||||
|
||||
if (!hasPermission) {
|
||||
throw new ForbiddenException(
|
||||
`You do not have permission to ${action} ${subject}`,
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to check if a subject value is a valid AbilitySubject.
|
||||
* @param subject - The subject value to check
|
||||
* @returns True if the subject is a valid AbilitySubject enum value
|
||||
*/
|
||||
private isValidSubject(subject: string): subject is AbilitySubject {
|
||||
return Object.values(AbilitySubject).includes(subject as AbilitySubject);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import { SetMetadata } from '@nestjs/common';
|
||||
import { AbilitySubject } from './Roles.types';
|
||||
|
||||
export const REQUIRED_PERMISSION_KEY = 'requiredPermission';
|
||||
|
||||
export interface RequiredPermission {
|
||||
ability: string;
|
||||
subject: AbilitySubject | string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decorator to specify required ability and subject for a route handler or controller.
|
||||
* @param ability - The ability/action required (e.g., 'Create', 'View', 'Edit', 'Delete')
|
||||
* @param subject - The subject/entity the ability applies to (e.g., AbilitySubject.Item, AbilitySubject.SaleInvoice)
|
||||
* @example
|
||||
* ```typescript
|
||||
* @RequirePermission('Create', AbilitySubject.Item)
|
||||
* @Post()
|
||||
* async createItem(@Body() dto: CreateItemDto) { ... }
|
||||
*
|
||||
* @RequirePermission('View', AbilitySubject.SaleInvoice)
|
||||
* @Get(':id')
|
||||
* async getInvoice(@Param('id') id: number) { ... }
|
||||
* ```
|
||||
*/
|
||||
export const RequirePermission = (
|
||||
ability: string,
|
||||
subject: AbilitySubject | string,
|
||||
) => SetMetadata(REQUIRED_PERMISSION_KEY, { ability, subject });
|
||||
@@ -10,6 +10,8 @@ import { RolePermission } from './models/RolePermission.model';
|
||||
import { RolesController } from './Roles.controller';
|
||||
import { RolesApplication } from './Roles.application';
|
||||
import { RolePermissionsSchema } from './queries/RolePermissionsSchema';
|
||||
import { AuthorizationGuard } from './Authorization.guard';
|
||||
import { PermissionGuard } from './Permission.guard';
|
||||
|
||||
const models = [
|
||||
RegisterTenancyModel(Role),
|
||||
@@ -25,9 +27,11 @@ const models = [
|
||||
GetRoleService,
|
||||
GetRolesService,
|
||||
RolesApplication,
|
||||
RolePermissionsSchema
|
||||
RolePermissionsSchema,
|
||||
AuthorizationGuard,
|
||||
PermissionGuard,
|
||||
],
|
||||
controllers: [RolesController],
|
||||
exports: [...models],
|
||||
exports: [...models, AuthorizationGuard, PermissionGuard],
|
||||
})
|
||||
export class RolesModule {}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { IsOptional } from '@/common/decorators/Validators';
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { Type } from 'class-transformer';
|
||||
import {
|
||||
@@ -41,7 +42,7 @@ export class CommandRolePermissionDto {
|
||||
export class CreateRolePermissionDto extends CommandRolePermissionDto { }
|
||||
export class EditRolePermissionDto extends CommandRolePermissionDto {
|
||||
@IsNumber()
|
||||
@IsNotEmpty()
|
||||
@IsOptional()
|
||||
@ApiProperty({
|
||||
example: 1,
|
||||
description: 'The permission ID',
|
||||
@@ -59,7 +60,6 @@ class CommandRoleDto {
|
||||
roleName: string;
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
@ApiProperty({
|
||||
example: 'Administrator',
|
||||
description: 'The description of the role',
|
||||
@@ -71,9 +71,9 @@ export class CreateRoleDto extends CommandRoleDto {
|
||||
@IsArray()
|
||||
@ArrayMinSize(1)
|
||||
@ValidateNested({ each: true })
|
||||
@Type(() => CommandRolePermissionDto)
|
||||
@Type(() => CreateRolePermissionDto)
|
||||
@ApiProperty({
|
||||
type: [CommandRolePermissionDto],
|
||||
type: [CreateRolePermissionDto],
|
||||
description: 'The permissions of the role',
|
||||
})
|
||||
permissions: Array<CreateRolePermissionDto>;
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
Put,
|
||||
Query,
|
||||
Res,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { SaleEstimatesApplication } from './SaleEstimates.application';
|
||||
import {
|
||||
@@ -40,6 +41,11 @@ import {
|
||||
BulkDeleteDto,
|
||||
ValidateBulkDeleteResponseDto,
|
||||
} from '@/common/dtos/BulkDelete.dto';
|
||||
import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator';
|
||||
import { PermissionGuard } from '@/modules/Roles/Permission.guard';
|
||||
import { AuthorizationGuard } from '@/modules/Roles/Authorization.guard';
|
||||
import { AbilitySubject } from '@/modules/Roles/Roles.types';
|
||||
import { SaleEstimateAction } from './types/SaleEstimates.types';
|
||||
|
||||
@Controller('sale-estimates')
|
||||
@ApiTags('Sale Estimates')
|
||||
@@ -48,8 +54,10 @@ import {
|
||||
@ApiExtraModels(SaleEstiamteStateResponseDto)
|
||||
@ApiCommonHeaders()
|
||||
@ApiExtraModels(ValidateBulkDeleteResponseDto)
|
||||
@UseGuards(AuthorizationGuard, PermissionGuard)
|
||||
export class SaleEstimatesController {
|
||||
@Post('validate-bulk-delete')
|
||||
@RequirePermission(SaleEstimateAction.Delete, AbilitySubject.SaleEstimate)
|
||||
@ApiOperation({
|
||||
summary:
|
||||
'Validates which sale estimates can be deleted and returns the results.',
|
||||
@@ -71,6 +79,7 @@ export class SaleEstimatesController {
|
||||
}
|
||||
|
||||
@Post('bulk-delete')
|
||||
@RequirePermission(SaleEstimateAction.Delete, AbilitySubject.SaleEstimate)
|
||||
@ApiOperation({ summary: 'Deletes multiple sale estimates.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -93,6 +102,7 @@ export class SaleEstimatesController {
|
||||
) { }
|
||||
|
||||
@Post()
|
||||
@RequirePermission(SaleEstimateAction.Create, AbilitySubject.SaleEstimate)
|
||||
@ApiOperation({ summary: 'Create a new sale estimate.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -105,6 +115,7 @@ export class SaleEstimatesController {
|
||||
}
|
||||
|
||||
@Put(':id')
|
||||
@RequirePermission(SaleEstimateAction.Edit, AbilitySubject.SaleEstimate)
|
||||
@ApiOperation({ summary: 'Edit the given sale estimate.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -131,6 +142,7 @@ export class SaleEstimatesController {
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@RequirePermission(SaleEstimateAction.Delete, AbilitySubject.SaleEstimate)
|
||||
@ApiOperation({ summary: 'Delete the given sale estimate.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -153,6 +165,7 @@ export class SaleEstimatesController {
|
||||
}
|
||||
|
||||
@Get('state')
|
||||
@RequirePermission(SaleEstimateAction.View, AbilitySubject.SaleEstimate)
|
||||
@ApiOperation({ summary: 'Retrieves the sale estimate state.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -166,6 +179,7 @@ export class SaleEstimatesController {
|
||||
}
|
||||
|
||||
@Get()
|
||||
@RequirePermission(SaleEstimateAction.View, AbilitySubject.SaleEstimate)
|
||||
@ApiOperation({ summary: 'Retrieves the sale estimates.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -189,6 +203,7 @@ export class SaleEstimatesController {
|
||||
}
|
||||
|
||||
@Post(':id/deliver')
|
||||
@RequirePermission(SaleEstimateAction.Edit, AbilitySubject.SaleEstimate)
|
||||
@ApiOperation({ summary: 'Deliver the given sale estimate.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -207,6 +222,7 @@ export class SaleEstimatesController {
|
||||
}
|
||||
|
||||
@Put(':id/approve')
|
||||
@RequirePermission(SaleEstimateAction.Edit, AbilitySubject.SaleEstimate)
|
||||
@ApiOperation({ summary: 'Approve the given sale estimate.' })
|
||||
@ApiParam({
|
||||
name: 'id',
|
||||
@@ -221,6 +237,7 @@ export class SaleEstimatesController {
|
||||
}
|
||||
|
||||
@Put(':id/reject')
|
||||
@RequirePermission(SaleEstimateAction.Edit, AbilitySubject.SaleEstimate)
|
||||
@ApiOperation({ summary: 'Reject the given sale estimate.' })
|
||||
@ApiParam({
|
||||
name: 'id',
|
||||
@@ -235,6 +252,7 @@ export class SaleEstimatesController {
|
||||
}
|
||||
|
||||
@Post(':id/notify-sms')
|
||||
@RequirePermission(SaleEstimateAction.NotifyBySms, AbilitySubject.SaleEstimate)
|
||||
@ApiOperation({ summary: 'Notify the given sale estimate by SMS.' })
|
||||
@ApiParam({
|
||||
name: 'id',
|
||||
@@ -251,6 +269,7 @@ export class SaleEstimatesController {
|
||||
}
|
||||
|
||||
@Get(':id/sms-details')
|
||||
@RequirePermission(SaleEstimateAction.View, AbilitySubject.SaleEstimate)
|
||||
@ApiOperation({ summary: 'Retrieves the sale estimate SMS details.' })
|
||||
public getSaleEstimateSmsDetails(
|
||||
@Param('id', ParseIntPipe) saleEstimateId: number,
|
||||
@@ -262,6 +281,7 @@ export class SaleEstimatesController {
|
||||
|
||||
@Post(':id/mail')
|
||||
@HttpCode(200)
|
||||
@RequirePermission(SaleEstimateAction.Edit, AbilitySubject.SaleEstimate)
|
||||
@ApiOperation({ summary: 'Send the given sale estimate by mail.' })
|
||||
@ApiParam({
|
||||
name: 'id',
|
||||
@@ -280,6 +300,7 @@ export class SaleEstimatesController {
|
||||
}
|
||||
|
||||
@Get(':id/mail')
|
||||
@RequirePermission(SaleEstimateAction.View, AbilitySubject.SaleEstimate)
|
||||
@ApiOperation({ summary: 'Retrieves the sale estimate mail state.' })
|
||||
@ApiParam({
|
||||
name: 'id',
|
||||
@@ -296,6 +317,7 @@ export class SaleEstimatesController {
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@RequirePermission(SaleEstimateAction.View, AbilitySubject.SaleEstimate)
|
||||
@ApiOperation({
|
||||
summary: 'Retrieves the sale estimate details.',
|
||||
})
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
Put,
|
||||
Query,
|
||||
Res,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import {
|
||||
ISaleInvoiceWriteoffDTO,
|
||||
@@ -43,6 +44,11 @@ import {
|
||||
BulkDeleteDto,
|
||||
ValidateBulkDeleteResponseDto,
|
||||
} from '@/common/dtos/BulkDelete.dto';
|
||||
import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator';
|
||||
import { PermissionGuard } from '@/modules/Roles/Permission.guard';
|
||||
import { AuthorizationGuard } from '@/modules/Roles/Authorization.guard';
|
||||
import { AbilitySubject } from '@/modules/Roles/Roles.types';
|
||||
import { SaleInvoiceAction } from './SaleInvoice.types';
|
||||
|
||||
@Controller('sale-invoices')
|
||||
@ApiTags('Sale Invoices')
|
||||
@@ -52,10 +58,12 @@ import {
|
||||
@ApiExtraModels(GenerateSaleInvoiceSharableLinkResponseDto)
|
||||
@ApiCommonHeaders()
|
||||
@ApiExtraModels(ValidateBulkDeleteResponseDto)
|
||||
@UseGuards(AuthorizationGuard, PermissionGuard)
|
||||
export class SaleInvoicesController {
|
||||
constructor(private saleInvoiceApplication: SaleInvoiceApplication) { }
|
||||
|
||||
@Post('validate-bulk-delete')
|
||||
@RequirePermission(SaleInvoiceAction.Delete, AbilitySubject.SaleInvoice)
|
||||
@ApiOperation({
|
||||
summary:
|
||||
'Validates which sale invoices can be deleted and returns the results.',
|
||||
@@ -77,6 +85,7 @@ export class SaleInvoicesController {
|
||||
}
|
||||
|
||||
@Post('bulk-delete')
|
||||
@RequirePermission(SaleInvoiceAction.Delete, AbilitySubject.SaleInvoice)
|
||||
@ApiOperation({ summary: 'Deletes multiple sale invoices.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -90,6 +99,7 @@ export class SaleInvoicesController {
|
||||
}
|
||||
|
||||
@Post()
|
||||
@RequirePermission(SaleInvoiceAction.Create, AbilitySubject.SaleInvoice)
|
||||
@ApiOperation({ summary: 'Create a new sale invoice.' })
|
||||
@ApiResponse({
|
||||
status: 201,
|
||||
@@ -121,6 +131,7 @@ export class SaleInvoicesController {
|
||||
}
|
||||
|
||||
@Put(':id')
|
||||
@RequirePermission(SaleInvoiceAction.Edit, AbilitySubject.SaleInvoice)
|
||||
@ApiOperation({ summary: 'Edit the given sale invoice.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -141,6 +152,7 @@ export class SaleInvoicesController {
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@RequirePermission(SaleInvoiceAction.Delete, AbilitySubject.SaleInvoice)
|
||||
@ApiOperation({ summary: 'Delete the given sale invoice.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -158,6 +170,7 @@ export class SaleInvoicesController {
|
||||
}
|
||||
|
||||
@Get('receivable')
|
||||
@RequirePermission(SaleInvoiceAction.View, AbilitySubject.SaleInvoice)
|
||||
@ApiOperation({ summary: 'Retrieves the receivable sale invoices.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -176,6 +189,7 @@ export class SaleInvoicesController {
|
||||
}
|
||||
|
||||
@Get('state')
|
||||
@RequirePermission(SaleInvoiceAction.View, AbilitySubject.SaleInvoice)
|
||||
@ApiOperation({ summary: 'Retrieves the sale invoice state.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -190,6 +204,7 @@ export class SaleInvoicesController {
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@RequirePermission(SaleInvoiceAction.View, AbilitySubject.SaleInvoice)
|
||||
@ApiOperation({ summary: 'Retrieves the sale invoice details.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -228,6 +243,7 @@ export class SaleInvoicesController {
|
||||
}
|
||||
|
||||
@Get()
|
||||
@RequirePermission(SaleInvoiceAction.View, AbilitySubject.SaleInvoice)
|
||||
@ApiOperation({ summary: 'Retrieves the sale invoices.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -251,6 +267,7 @@ export class SaleInvoicesController {
|
||||
}
|
||||
|
||||
@Put(':id/deliver')
|
||||
@RequirePermission(SaleInvoiceAction.Edit, AbilitySubject.SaleInvoice)
|
||||
@ApiOperation({ summary: 'Deliver the given sale invoice.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -269,6 +286,7 @@ export class SaleInvoicesController {
|
||||
}
|
||||
|
||||
@Post(':id/writeoff')
|
||||
@RequirePermission(SaleInvoiceAction.Writeoff, AbilitySubject.SaleInvoice)
|
||||
@ApiOperation({ summary: 'Write off the given sale invoice.' })
|
||||
@HttpCode(200)
|
||||
@ApiResponse({
|
||||
@@ -290,6 +308,7 @@ export class SaleInvoicesController {
|
||||
}
|
||||
|
||||
@Post(':id/cancel-writeoff')
|
||||
@RequirePermission(SaleInvoiceAction.Writeoff, AbilitySubject.SaleInvoice)
|
||||
@ApiOperation({ summary: 'Cancel the written off sale invoice.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -309,6 +328,7 @@ export class SaleInvoicesController {
|
||||
}
|
||||
|
||||
@Get(':id/payments')
|
||||
@RequirePermission(SaleInvoiceAction.View, AbilitySubject.SaleInvoice)
|
||||
@ApiOperation({ summary: 'Retrieves the sale invoice payments.' })
|
||||
@ApiResponse({ status: 404, description: 'The sale invoice not found.' })
|
||||
@ApiParam({
|
||||
@@ -322,6 +342,7 @@ export class SaleInvoicesController {
|
||||
}
|
||||
|
||||
@Get(':id/html')
|
||||
@RequirePermission(SaleInvoiceAction.View, AbilitySubject.SaleInvoice)
|
||||
@ApiOperation({ summary: 'Retrieves the sale invoice HTML.' })
|
||||
@ApiResponse({ status: 404, description: 'The sale invoice not found.' })
|
||||
@ApiParam({
|
||||
@@ -335,6 +356,7 @@ export class SaleInvoicesController {
|
||||
}
|
||||
|
||||
@Get(':id/mail')
|
||||
@RequirePermission(SaleInvoiceAction.View, AbilitySubject.SaleInvoice)
|
||||
@ApiOperation({ summary: 'Retrieves the sale invoice mail state.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -354,6 +376,7 @@ export class SaleInvoicesController {
|
||||
}
|
||||
|
||||
@Post(':id/generate-link')
|
||||
@RequirePermission(SaleInvoiceAction.Edit, AbilitySubject.SaleInvoice)
|
||||
@ApiOperation({
|
||||
summary: 'Generate sharable sale invoice link (private or public)',
|
||||
})
|
||||
|
||||
@@ -1,16 +1,22 @@
|
||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||
import { Body, Controller, Get, Put } from '@nestjs/common';
|
||||
import { Body, Controller, Get, Put, UseGuards } from '@nestjs/common';
|
||||
import { SettingsApplicationService } from './SettingsApplication.service';
|
||||
import { ISettingsDTO } from './Settings.types';
|
||||
import { ISettingsDTO, PreferencesAction } from './Settings.types';
|
||||
import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator';
|
||||
import { PermissionGuard } from '@/modules/Roles/Permission.guard';
|
||||
import { AuthorizationGuard } from '@/modules/Roles/Authorization.guard';
|
||||
import { AbilitySubject } from '@/modules/Roles/Roles.types';
|
||||
|
||||
@Controller('settings')
|
||||
@ApiTags('Settings')
|
||||
@UseGuards(AuthorizationGuard, PermissionGuard)
|
||||
export class SettingsController {
|
||||
constructor(
|
||||
private readonly settingsApplicationService: SettingsApplicationService,
|
||||
) {}
|
||||
|
||||
@Put()
|
||||
@RequirePermission(PreferencesAction.Mutate, AbilitySubject.Preferences)
|
||||
@ApiOperation({ summary: 'Save the given settings.' })
|
||||
async saveSettings(@Body() settingsDTO: ISettingsDTO) {
|
||||
return this.settingsApplicationService.saveSettings(settingsDTO);
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
Param,
|
||||
Post,
|
||||
Put,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { TaxRatesApplication } from './TaxRate.application';
|
||||
import {
|
||||
@@ -18,15 +19,22 @@ import {
|
||||
import { CreateTaxRateDto, EditTaxRateDto } from './dtos/TaxRate.dto';
|
||||
import { TaxRateResponseDto } from './dtos/TaxRateResponse.dto';
|
||||
import { ApiCommonHeaders } from '@/common/decorators/ApiCommonHeaders';
|
||||
import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator';
|
||||
import { PermissionGuard } from '@/modules/Roles/Permission.guard';
|
||||
import { AuthorizationGuard } from '@/modules/Roles/Authorization.guard';
|
||||
import { AbilitySubject } from '@/modules/Roles/Roles.types';
|
||||
import { TaxRateAction } from './TaxRates.types';
|
||||
|
||||
@Controller('tax-rates')
|
||||
@ApiTags('Tax Rates')
|
||||
@ApiExtraModels(TaxRateResponseDto)
|
||||
@ApiCommonHeaders()
|
||||
@UseGuards(AuthorizationGuard, PermissionGuard)
|
||||
export class TaxRatesController {
|
||||
constructor(private readonly taxRatesApplication: TaxRatesApplication) { }
|
||||
|
||||
@Post()
|
||||
@RequirePermission(TaxRateAction.CREATE, AbilitySubject.TaxRate)
|
||||
@ApiOperation({ summary: 'Create a new tax rate.' })
|
||||
@ApiResponse({
|
||||
status: 201,
|
||||
@@ -38,6 +46,7 @@ export class TaxRatesController {
|
||||
}
|
||||
|
||||
@Put(':id')
|
||||
@RequirePermission(TaxRateAction.EDIT, AbilitySubject.TaxRate)
|
||||
@ApiOperation({ summary: 'Edit the given tax rate.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -54,6 +63,7 @@ export class TaxRatesController {
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@RequirePermission(TaxRateAction.DELETE, AbilitySubject.TaxRate)
|
||||
@ApiOperation({ summary: 'Delete the given tax rate.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -67,6 +77,7 @@ export class TaxRatesController {
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@RequirePermission(TaxRateAction.VIEW, AbilitySubject.TaxRate)
|
||||
@ApiOperation({ summary: 'Retrieves the tax rate details.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -80,6 +91,7 @@ export class TaxRatesController {
|
||||
}
|
||||
|
||||
@Get()
|
||||
@RequirePermission(TaxRateAction.VIEW, AbilitySubject.TaxRate)
|
||||
@ApiOperation({ summary: 'Retrieves the tax rates.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -101,6 +113,7 @@ export class TaxRatesController {
|
||||
}
|
||||
|
||||
@Put(':id/activate')
|
||||
@RequirePermission(TaxRateAction.EDIT, AbilitySubject.TaxRate)
|
||||
@ApiOperation({ summary: 'Activate the given tax rate.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -114,6 +127,7 @@ export class TaxRatesController {
|
||||
}
|
||||
|
||||
@Put(':id/inactivate')
|
||||
@RequirePermission(TaxRateAction.EDIT, AbilitySubject.TaxRate)
|
||||
@ApiOperation({ summary: 'Inactivate the given tax rate.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
|
||||
@@ -22,7 +22,7 @@ export class UsersController {
|
||||
/**
|
||||
* Edit details of the given user.
|
||||
*/
|
||||
@Post(':id')
|
||||
@Put(':id')
|
||||
@ApiOperation({ summary: 'Edit details of the given user.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
|
||||
@@ -43,11 +43,11 @@ export class InactivateUserService {
|
||||
// Throw serivce error if the user is already inactivated.
|
||||
this.throwErrorIfUserInactive(tenantUser);
|
||||
|
||||
// Marks the tenant user as active.
|
||||
// Marks the tenant user as inactive.
|
||||
await this.tenantUserModel()
|
||||
.query()
|
||||
.findById(userId)
|
||||
.update({ active: true });
|
||||
.update({ active: false });
|
||||
|
||||
// Triggers `onTenantUserActivated` event.
|
||||
await this.eventEmitter.emitAsync(events.tenantUser.onInactivated, {
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
Post,
|
||||
Put,
|
||||
Query,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { VendorCreditsApplicationService } from './VendorCreditsApplication.service';
|
||||
import { IVendorCreditsQueryDTO } from './types/VendorCredit.types';
|
||||
@@ -26,17 +27,24 @@ import {
|
||||
BulkDeleteDto,
|
||||
ValidateBulkDeleteResponseDto,
|
||||
} from '@/common/dtos/BulkDelete.dto';
|
||||
import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator';
|
||||
import { PermissionGuard } from '@/modules/Roles/Permission.guard';
|
||||
import { AuthorizationGuard } from '@/modules/Roles/Authorization.guard';
|
||||
import { AbilitySubject } from '@/modules/Roles/Roles.types';
|
||||
import { VendorCreditAction } from './types/VendorCredit.types';
|
||||
|
||||
@Controller('vendor-credits')
|
||||
@ApiTags('Vendor Credits')
|
||||
@ApiCommonHeaders()
|
||||
@ApiExtraModels(ValidateBulkDeleteResponseDto)
|
||||
@UseGuards(AuthorizationGuard, PermissionGuard)
|
||||
export class VendorCreditsController {
|
||||
constructor(
|
||||
private readonly vendorCreditsApplication: VendorCreditsApplicationService,
|
||||
) { }
|
||||
|
||||
@Post('validate-bulk-delete')
|
||||
@RequirePermission(VendorCreditAction.Delete, AbilitySubject.VendorCredit)
|
||||
@ApiOperation({
|
||||
summary:
|
||||
'Validates which vendor credits can be deleted and returns the results.',
|
||||
@@ -58,6 +66,7 @@ export class VendorCreditsController {
|
||||
}
|
||||
|
||||
@Post('bulk-delete')
|
||||
@RequirePermission(VendorCreditAction.Delete, AbilitySubject.VendorCredit)
|
||||
@ApiOperation({ summary: 'Deletes multiple vendor credits.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -73,24 +82,28 @@ export class VendorCreditsController {
|
||||
}
|
||||
|
||||
@Post()
|
||||
@RequirePermission(VendorCreditAction.Create, AbilitySubject.VendorCredit)
|
||||
@ApiOperation({ summary: 'Create a new vendor credit.' })
|
||||
async createVendorCredit(@Body() dto: CreateVendorCreditDto) {
|
||||
return this.vendorCreditsApplication.createVendorCredit(dto);
|
||||
}
|
||||
|
||||
@Put(':id/open')
|
||||
@RequirePermission(VendorCreditAction.Edit, AbilitySubject.VendorCredit)
|
||||
@ApiOperation({ summary: 'Open the given vendor credit.' })
|
||||
async openVendorCredit(@Param('id') vendorCreditId: number) {
|
||||
return this.vendorCreditsApplication.openVendorCredit(vendorCreditId);
|
||||
}
|
||||
|
||||
@Get()
|
||||
@RequirePermission(VendorCreditAction.View, AbilitySubject.VendorCredit)
|
||||
@ApiOperation({ summary: 'Retrieves the vendor credits.' })
|
||||
async getVendorCredits(@Query() filterDTO: IVendorCreditsQueryDTO) {
|
||||
return this.vendorCreditsApplication.getVendorCredits(filterDTO);
|
||||
}
|
||||
|
||||
@Put(':id')
|
||||
@RequirePermission(VendorCreditAction.Edit, AbilitySubject.VendorCredit)
|
||||
@ApiOperation({ summary: 'Edit the given vendor credit.' })
|
||||
async editVendorCredit(
|
||||
@Param('id') vendorCreditId: number,
|
||||
@@ -100,12 +113,14 @@ export class VendorCreditsController {
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@RequirePermission(VendorCreditAction.Delete, AbilitySubject.VendorCredit)
|
||||
@ApiOperation({ summary: 'Delete the given vendor credit.' })
|
||||
async deleteVendorCredit(@Param('id') vendorCreditId: number) {
|
||||
return this.vendorCreditsApplication.deleteVendorCredit(vendorCreditId);
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@RequirePermission(VendorCreditAction.View, AbilitySubject.VendorCredit)
|
||||
@ApiOperation({ summary: 'Retrieves the vendor credit details.' })
|
||||
async getVendorCredit(@Param('id') vendorCreditId: number) {
|
||||
return this.vendorCreditsApplication.getVendorCredit(vendorCreditId);
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
Post,
|
||||
Put,
|
||||
Query,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { VendorsApplication } from './VendorsApplication.service';
|
||||
import { VendorOpeningBalanceEditDto } from './dtos/VendorOpeningBalanceEdit.dto';
|
||||
@@ -24,44 +25,56 @@ import {
|
||||
BulkDeleteVendorsDto,
|
||||
ValidateBulkDeleteVendorsResponseDto,
|
||||
} from './dtos/BulkDeleteVendors.dto';
|
||||
import { RequirePermission } from '@/modules/Roles/RequirePermission.decorator';
|
||||
import { PermissionGuard } from '@/modules/Roles/Permission.guard';
|
||||
import { AuthorizationGuard } from '@/modules/Roles/Authorization.guard';
|
||||
import { AbilitySubject } from '@/modules/Roles/Roles.types';
|
||||
import { VendorAction } from '../Customers/types/Customers.types';
|
||||
|
||||
@Controller('vendors')
|
||||
@ApiTags('Vendors')
|
||||
@ApiCommonHeaders()
|
||||
@UseGuards(AuthorizationGuard, PermissionGuard)
|
||||
export class VendorsController {
|
||||
constructor(private vendorsApplication: VendorsApplication) {}
|
||||
|
||||
@Get()
|
||||
@RequirePermission(VendorAction.View, AbilitySubject.Vendor)
|
||||
@ApiOperation({ summary: 'Retrieves the vendors.' })
|
||||
getVendors(@Query() filterDTO: GetVendorsQueryDto) {
|
||||
return this.vendorsApplication.getVendors(filterDTO);
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@RequirePermission(VendorAction.View, AbilitySubject.Vendor)
|
||||
@ApiOperation({ summary: 'Retrieves the vendor details.' })
|
||||
getVendor(@Param('id') vendorId: number) {
|
||||
return this.vendorsApplication.getVendor(vendorId);
|
||||
}
|
||||
|
||||
@Post()
|
||||
@RequirePermission(VendorAction.Create, AbilitySubject.Vendor)
|
||||
@ApiOperation({ summary: 'Create a new vendor.' })
|
||||
createVendor(@Body() vendorDTO: CreateVendorDto) {
|
||||
return this.vendorsApplication.createVendor(vendorDTO);
|
||||
}
|
||||
|
||||
@Put(':id')
|
||||
@RequirePermission(VendorAction.Edit, AbilitySubject.Vendor)
|
||||
@ApiOperation({ summary: 'Edit the given vendor.' })
|
||||
editVendor(@Param('id') vendorId: number, @Body() vendorDTO: EditVendorDto) {
|
||||
return this.vendorsApplication.editVendor(vendorId, vendorDTO);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@RequirePermission(VendorAction.Delete, AbilitySubject.Vendor)
|
||||
@ApiOperation({ summary: 'Delete the given vendor.' })
|
||||
deleteVendor(@Param('id') vendorId: number) {
|
||||
return this.vendorsApplication.deleteVendor(vendorId);
|
||||
}
|
||||
|
||||
@Put(':id/opening-balance')
|
||||
@RequirePermission(VendorAction.Edit, AbilitySubject.Vendor)
|
||||
@ApiOperation({ summary: 'Edit the given vendor opening balance.' })
|
||||
editOpeningBalance(
|
||||
@Param('id') vendorId: number,
|
||||
@@ -74,6 +87,7 @@ export class VendorsController {
|
||||
}
|
||||
|
||||
@Post('validate-bulk-delete')
|
||||
@RequirePermission(VendorAction.Delete, AbilitySubject.Vendor)
|
||||
@ApiOperation({
|
||||
summary:
|
||||
'Validates which vendors can be deleted and returns counts of deletable and non-deletable vendors.',
|
||||
@@ -93,6 +107,7 @@ export class VendorsController {
|
||||
}
|
||||
|
||||
@Post('bulk-delete')
|
||||
@RequirePermission(VendorAction.Delete, AbilitySubject.Vendor)
|
||||
@ApiOperation({ summary: 'Deletes multiple vendors in bulk.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
|
||||
@@ -57,7 +57,7 @@ function GlobalErrors({
|
||||
if (globalErrors.access_denied) {
|
||||
toastKeySomethingWrong = AppToaster.show(
|
||||
{
|
||||
message: intl.get('global_error.you_dont_have_permissions'),
|
||||
message: globalErrors.access_denied.message || intl.get('global_error.you_dont_have_permissions'),
|
||||
intent: Intent.DANGER,
|
||||
onDismiss: () => {
|
||||
globalErrorsSet({ access_denied: false });
|
||||
|
||||
@@ -58,7 +58,7 @@ export default function useApiRequest() {
|
||||
setLogout();
|
||||
}
|
||||
if (status === 403) {
|
||||
setGlobalErrors({ access_denied: true });
|
||||
setGlobalErrors({ access_denied: { message: data.message } });
|
||||
}
|
||||
if (status === 429) {
|
||||
setGlobalErrors({ too_many_requests: true });
|
||||
|
||||
Reference in New Issue
Block a user