mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-15 12:20:31 +00:00
279 lines
7.5 KiB
TypeScript
279 lines
7.5 KiB
TypeScript
import { Inject, Service } from 'typedi';
|
|
import { Router, Request, Response } from 'express';
|
|
import { body, param } from 'express-validator';
|
|
import BaseController from '@/api/controllers/BaseController';
|
|
import asyncMiddleware from '@/api/middleware/asyncMiddleware';
|
|
import { TaxRatesApplication } from '@/services/TaxRates/TaxRatesApplication';
|
|
import CheckAbilities from '@/api/middleware/CheckPolicies';
|
|
import { ServiceError } from '@/exceptions';
|
|
import { ERRORS } from '@/services/TaxRates/constants';
|
|
import { AbilitySubject, TaxRateAction } from '@/interfaces';
|
|
|
|
@Service()
|
|
export class TaxRatesController extends BaseController {
|
|
@Inject()
|
|
private taxRatesApplication: TaxRatesApplication;
|
|
|
|
/**
|
|
* Router constructor.
|
|
*/
|
|
public router() {
|
|
const router = Router();
|
|
|
|
router.post(
|
|
'/',
|
|
CheckAbilities(TaxRateAction.CREATE, AbilitySubject.TaxRate),
|
|
this.taxRateValidationSchema,
|
|
this.validationResult,
|
|
asyncMiddleware(this.createTaxRate.bind(this)),
|
|
this.handleServiceErrors
|
|
);
|
|
router.post(
|
|
'/:id',
|
|
CheckAbilities(TaxRateAction.EDIT, AbilitySubject.TaxRate),
|
|
[param('id').exists().toInt(), ...this.taxRateValidationSchema],
|
|
this.validationResult,
|
|
asyncMiddleware(this.editTaxRate.bind(this)),
|
|
this.handleServiceErrors
|
|
);
|
|
router.post(
|
|
'/:id/active',
|
|
CheckAbilities(TaxRateAction.EDIT, AbilitySubject.TaxRate),
|
|
[param('id').exists().toInt()],
|
|
this.validationResult,
|
|
asyncMiddleware(this.activateTaxRate.bind(this)),
|
|
this.handleServiceErrors
|
|
);
|
|
router.post(
|
|
'/:id/inactive',
|
|
CheckAbilities(TaxRateAction.EDIT, AbilitySubject.TaxRate),
|
|
[param('id').exists().toInt()],
|
|
this.validationResult,
|
|
asyncMiddleware(this.inactivateTaxRate.bind(this)),
|
|
this.handleServiceErrors
|
|
);
|
|
router.delete(
|
|
'/:id',
|
|
CheckAbilities(TaxRateAction.DELETE, AbilitySubject.TaxRate),
|
|
[param('id').exists().toInt()],
|
|
this.validationResult,
|
|
asyncMiddleware(this.deleteTaxRate.bind(this)),
|
|
this.handleServiceErrors
|
|
);
|
|
router.get(
|
|
'/:id',
|
|
CheckAbilities(TaxRateAction.VIEW, AbilitySubject.TaxRate),
|
|
[param('id').exists().toInt()],
|
|
this.validationResult,
|
|
asyncMiddleware(this.getTaxRate.bind(this)),
|
|
this.handleServiceErrors
|
|
);
|
|
router.get(
|
|
'/',
|
|
CheckAbilities(TaxRateAction.VIEW, AbilitySubject.TaxRate),
|
|
this.validationResult,
|
|
asyncMiddleware(this.getTaxRates.bind(this)),
|
|
this.handleServiceErrors
|
|
);
|
|
return router;
|
|
}
|
|
|
|
/**
|
|
* Tax rate validation schema.
|
|
*/
|
|
private get taxRateValidationSchema() {
|
|
return [
|
|
body('name').exists(),
|
|
body('code').exists().isString(),
|
|
body('rate').exists().isNumeric().toFloat(),
|
|
body('description').optional().trim().isString(),
|
|
body('is_non_recoverable').optional().isBoolean().default(false),
|
|
body('is_compound').optional().isBoolean().default(false),
|
|
body('active').optional().isBoolean().default(false),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Creates a new tax rate.
|
|
* @param {Request} req -
|
|
* @param {Response} res -
|
|
*/
|
|
public async createTaxRate(req: Request, res: Response, next) {
|
|
const { tenantId } = req;
|
|
const createTaxRateDTO = this.matchedBodyData(req);
|
|
|
|
try {
|
|
const taxRate = await this.taxRatesApplication.createTaxRate(
|
|
tenantId,
|
|
createTaxRateDTO
|
|
);
|
|
return res.status(200).send({
|
|
data: taxRate,
|
|
});
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Edits the given tax rate.
|
|
* @param {Request} req -
|
|
* @param {Response} res -
|
|
*/
|
|
public async editTaxRate(req: Request, res: Response, next) {
|
|
const { tenantId } = req;
|
|
const editTaxRateDTO = this.matchedBodyData(req);
|
|
const { id: taxRateId } = req.params;
|
|
|
|
try {
|
|
const taxRate = await this.taxRatesApplication.editTaxRate(
|
|
tenantId,
|
|
taxRateId,
|
|
editTaxRateDTO
|
|
);
|
|
return res.status(200).send({
|
|
data: taxRate,
|
|
});
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Deletes the given tax rate.
|
|
* @param {Request} req -
|
|
* @param {Response} res -
|
|
*/
|
|
public async deleteTaxRate(req: Request, res: Response, next) {
|
|
const { tenantId } = req;
|
|
const { id: taxRateId } = req.params;
|
|
|
|
try {
|
|
await this.taxRatesApplication.deleteTaxRate(tenantId, taxRateId);
|
|
|
|
return res.status(200).send({
|
|
code: 200,
|
|
message: 'The tax rate has been deleted successfully.',
|
|
});
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Retrieves the given tax rate.
|
|
* @param {Request} req -
|
|
* @param {Response} res -
|
|
*/
|
|
public async getTaxRate(req: Request, res: Response, next) {
|
|
const { tenantId } = req;
|
|
const { id: taxRateId } = req.params;
|
|
|
|
try {
|
|
const taxRate = await this.taxRatesApplication.getTaxRate(
|
|
tenantId,
|
|
taxRateId
|
|
);
|
|
return res.status(200).send({ data: taxRate });
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Retrieves the tax rates list.
|
|
* @param {Request} req -
|
|
* @param {Response} res -
|
|
*/
|
|
public async getTaxRates(req: Request, res: Response, next) {
|
|
const { tenantId } = req;
|
|
|
|
try {
|
|
const taxRates = await this.taxRatesApplication.getTaxRates(tenantId);
|
|
|
|
return res.status(200).send({ data: taxRates });
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Inactivates the given tax rate.
|
|
* @param req
|
|
* @param res
|
|
* @param next
|
|
* @returns
|
|
*/
|
|
public async inactivateTaxRate(req: Request, res: Response, next) {
|
|
const { tenantId } = req;
|
|
const { id: taxRateId } = req.params;
|
|
|
|
try {
|
|
await this.taxRatesApplication.inactivateTaxRate(tenantId, taxRateId);
|
|
|
|
return res.status(200).send({
|
|
id: taxRateId,
|
|
message: 'The given tax rate has been inactivated successfully.',
|
|
});
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Inactivates the given tax rate.
|
|
* @param {Request} req
|
|
* @param {Response} res
|
|
* @param {NextFunction} next
|
|
* @returns
|
|
*/
|
|
public async activateTaxRate(req: Request, res: Response, next) {
|
|
const { tenantId } = req;
|
|
const { id: taxRateId } = req.params;
|
|
|
|
try {
|
|
await this.taxRatesApplication.activateTaxRate(tenantId, taxRateId);
|
|
|
|
return res.status(200).send({
|
|
id: taxRateId,
|
|
message: 'The given tax rate has been activated successfully.',
|
|
});
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handles service errors.
|
|
* @param {Error} error
|
|
* @param {Request} req
|
|
* @param {Response} res
|
|
* @param {NextFunction} next
|
|
*/
|
|
private handleServiceErrors(error: Error, req: Request, res: Response, next) {
|
|
if (error instanceof ServiceError) {
|
|
if (error.errorType === ERRORS.TAX_CODE_NOT_UNIQUE) {
|
|
return res.boom.badRequest(null, {
|
|
errors: [{ type: ERRORS.TAX_CODE_NOT_UNIQUE, code: 100 }],
|
|
});
|
|
}
|
|
if (error.errorType === ERRORS.TAX_RATE_NOT_FOUND) {
|
|
return res.boom.badRequest(null, {
|
|
errors: [{ type: ERRORS.TAX_RATE_NOT_FOUND, code: 200 }],
|
|
});
|
|
}
|
|
if (error.errorType === ERRORS.TAX_RATE_ALREADY_INACTIVE) {
|
|
return res.boom.badRequest(null, {
|
|
errors: [{ type: ERRORS.TAX_RATE_ALREADY_INACTIVE, code: 300 }],
|
|
});
|
|
}
|
|
if (error.errorType === ERRORS.TAX_RATE_ALREADY_ACTIVE) {
|
|
return res.boom.badRequest(null, {
|
|
errors: [{ type: ERRORS.TAX_RATE_ALREADY_ACTIVE, code: 400 }],
|
|
});
|
|
}
|
|
}
|
|
next(error);
|
|
}
|
|
}
|