refactoring: bills service.

refactoring: bills payments made service.
This commit is contained in:
Ahmed Bouhuolia
2020-10-15 15:10:41 +02:00
parent 8713c77289
commit 899ea7a52d
39 changed files with 2192 additions and 1193 deletions

View File

@@ -1,4 +1,4 @@
import { Router, Request, Response } from 'express';
import { Router, Request, Response, NextFunction } from 'express';
import { check, param, query, matchedData } from 'express-validator';
import { Inject, Service } from 'typedi';
import { ISaleEstimate, ISaleEstimateOTD } from 'interfaces';
@@ -25,9 +25,9 @@ export default class SalesEstimatesController extends BaseController {
'/',
this.estimateValidationSchema,
this.validationResult,
asyncMiddleware(this.validateEstimateCustomerExistance.bind(this)),
asyncMiddleware(this.validateEstimateNumberExistance.bind(this)),
asyncMiddleware(this.validateEstimateEntriesItemsExistance.bind(this)),
// asyncMiddleware(this.validateEstimateCustomerExistance.bind(this)),
// asyncMiddleware(this.validateEstimateNumberExistance.bind(this)),
// asyncMiddleware(this.validateEstimateEntriesItemsExistance.bind(this)),
asyncMiddleware(this.newEstimate.bind(this))
);
router.post(
@@ -36,11 +36,11 @@ export default class SalesEstimatesController extends BaseController {
...this.estimateValidationSchema,
],
this.validationResult,
asyncMiddleware(this.validateEstimateIdExistance.bind(this)),
asyncMiddleware(this.validateEstimateCustomerExistance.bind(this)),
asyncMiddleware(this.validateEstimateNumberExistance.bind(this)),
asyncMiddleware(this.validateEstimateEntriesItemsExistance.bind(this)),
asyncMiddleware(this.valdiateInvoiceEntriesIdsExistance.bind(this)),
// asyncMiddleware(this.validateEstimateIdExistance.bind(this)),
// asyncMiddleware(this.validateEstimateCustomerExistance.bind(this)),
// asyncMiddleware(this.validateEstimateNumberExistance.bind(this)),
// asyncMiddleware(this.validateEstimateEntriesItemsExistance.bind(this)),
// asyncMiddleware(this.valdiateInvoiceEntriesIdsExistance.bind(this)),
asyncMiddleware(this.editEstimate.bind(this))
);
router.delete(
@@ -48,14 +48,14 @@ export default class SalesEstimatesController extends BaseController {
this.validateSpecificEstimateSchema,
],
this.validationResult,
asyncMiddleware(this.validateEstimateIdExistance.bind(this)),
// asyncMiddleware(this.validateEstimateIdExistance.bind(this)),
asyncMiddleware(this.deleteEstimate.bind(this))
);
router.get(
'/:id',
this.validateSpecificEstimateSchema,
this.validationResult,
asyncMiddleware(this.validateEstimateIdExistance.bind(this)),
// asyncMiddleware(this.validateEstimateIdExistance.bind(this)),
asyncMiddleware(this.getEstimate.bind(this))
);
router.get(
@@ -114,120 +114,6 @@ export default class SalesEstimatesController extends BaseController {
]
}
/**
* Validate whether the estimate customer exists on the storage.
* @param {Request} req
* @param {Response} res
* @param {Function} next
*/
async validateEstimateCustomerExistance(req: Request, res: Response, next: Function) {
const estimate = { ...req.body };
const { Customer } = req.models
const foundCustomer = await Customer.query().findById(estimate.customer_id);
if (!foundCustomer) {
return res.status(404).send({
errors: [{ type: 'CUSTOMER.ID.NOT.FOUND', code: 200 }],
});
}
next();
}
/**
* Validate the estimate number unique on the storage.
* @param {Request} req
* @param {Response} res
* @param {Function} next
*/
async validateEstimateNumberExistance(req: Request, res: Response, next: Function) {
const estimate = { ...req.body };
const { tenantId } = req;
const isEstNumberUnqiue = await this.saleEstimateService.isEstimateNumberUnique(
tenantId,
estimate.estimate_number,
req.params.id,
);
if (isEstNumberUnqiue) {
return res.boom.badRequest(null, {
errors: [{ type: 'ESTIMATE.NUMBER.IS.NOT.UNQIUE', code: 300 }],
});
}
next();
}
/**
* Validate the estimate entries items ids existance on the storage.
* @param {Request} req
* @param {Response} res
* @param {Function} next
*/
async validateEstimateEntriesItemsExistance(req: Request, res: Response, next: Function) {
const tenantId = req.tenantId;
const estimate = { ...req.body };
const estimateItemsIds = estimate.entries.map(e => e.item_id);
// Validate items ids in estimate entries exists.
const notFoundItemsIds = await this.itemsService.isItemsIdsExists(tenantId, estimateItemsIds);
if (notFoundItemsIds.length > 0) {
return res.boom.badRequest(null, {
errors: [{ type: 'ITEMS.IDS.NOT.EXISTS', code: 400 }],
});
}
next();
}
/**
* Validate whether the sale estimate id exists on the storage.
* @param {Request} req
* @param {Response} res
* @param {Function} next
*/
async validateEstimateIdExistance(req: Request, res: Response, next: Function) {
const { id: estimateId } = req.params;
const { tenantId } = req;
const storedEstimate = await this.saleEstimateService
.getEstimate(tenantId, estimateId);
if (!storedEstimate) {
return res.status(404).send({
errors: [{ type: 'SALE.ESTIMATE.ID.NOT.FOUND', code: 200 }],
});
}
next();
}
/**
* Validate sale invoice entries ids existance on the storage.
* @param {Request} req
* @param {Response} res
* @param {Function} next
*/
async valdiateInvoiceEntriesIdsExistance(req: Request, res: Response, next: Function) {
const { ItemEntry } = req.models;
const { id: saleInvoiceId } = req.params;
const saleInvoice = { ...req.body };
const entriesIds = saleInvoice.entries
.filter(e => e.id)
.map((e) => e.id);
const foundEntries = await ItemEntry.query()
.whereIn('id', entriesIds)
.where('reference_type', 'SaleInvoice')
.where('reference_id', saleInvoiceId);
if (foundEntries.length > 0) {
return res.status(400).send({
errors: [{ type: 'ENTRIES.IDS.NOT.EXISTS', code: 300 }],
});
}
next();
}
/**
* Handle create a new estimate with associated entries.
* @param {Request} req -

View File

@@ -32,7 +32,7 @@ export default class SaleInvoicesController extends BaseController{
this.saleInvoiceValidationSchema,
this.validationResult,
asyncMiddleware(this.validateInvoiceCustomerExistance.bind(this)),
asyncMiddleware(this.validateInvoiceNumberUnique.bind(this)),
// asyncMiddleware(this.validateInvoiceNumberUnique.bind(this)),
asyncMiddleware(this.validateInvoiceItemsIdsExistance.bind(this)),
asyncMiddleware(this.validateNonSellableEntriesItems.bind(this)),
asyncMiddleware(this.newSaleInvoice.bind(this))
@@ -46,7 +46,7 @@ export default class SaleInvoicesController extends BaseController{
this.validationResult,
asyncMiddleware(this.validateInvoiceExistance.bind(this)),
asyncMiddleware(this.validateInvoiceCustomerExistance.bind(this)),
asyncMiddleware(this.validateInvoiceNumberUnique.bind(this)),
// asyncMiddleware(this.validateInvoiceNumberUnique.bind(this)),
asyncMiddleware(this.validateInvoiceItemsIdsExistance.bind(this)),
asyncMiddleware(this.valdiateInvoiceEntriesIdsExistance.bind(this)),
asyncMiddleware(this.validateEntriesIdsExistance.bind(this)),
@@ -312,18 +312,19 @@ export default class SaleInvoicesController extends BaseController{
* @param {Response} res
* @param {Function} next
*/
async newSaleInvoice(req: Request, res: Response) {
async newSaleInvoice(req: Request, res: Response, next: NextFunction) {
const { tenantId } = req;
const saleInvoiceOTD: ISaleInvoiceOTD = matchedData(req, {
locations: ['body'],
includeOptionals: true
});
const saleInvoiceOTD: ISaleInvoiceOTD = this.matchedBodyData(req);
// Creates a new sale invoice with associated entries.
const storedSaleInvoice = await this.saleInvoiceService.createSaleInvoice(
tenantId, saleInvoiceOTD,
);
return res.status(200).send({ id: storedSaleInvoice.id });
try {
// Creates a new sale invoice with associated entries.
const storedSaleInvoice = await this.saleInvoiceService.createSaleInvoice(
tenantId, saleInvoiceOTD,
);
return res.status(200).send({ id: storedSaleInvoice.id });
} catch (error) {
next(error)
}
}
/**
@@ -332,18 +333,18 @@ export default class SaleInvoicesController extends BaseController{
* @param {Response} res
* @param {Function} next
*/
async editSaleInvoice(req: Request, res: Response) {
async editSaleInvoice(req: Request, res: Response, next: NextFunction) {
const { tenantId } = req;
const { id: saleInvoiceId } = req.params;
const saleInvoiceOTD: ISaleInvoiceOTD = this.matchedBodyData(req);
const saleInvoiceOTD: ISaleInvoiceOTD = matchedData(req, {
locations: ['body'],
includeOptionals: true
});
// Update the given sale invoice details.
await this.saleInvoiceService.editSaleInvoice(tenantId, saleInvoiceId, saleInvoiceOTD);
return res.status(200).send({ id: saleInvoiceId });
try {
// Update the given sale invoice details.
await this.saleInvoiceService.editSaleInvoice(tenantId, saleInvoiceId, saleInvoiceOTD);
return res.status(200).send({ id: saleInvoiceId });
} catch (error) {
next(error);
}
}
/**
@@ -352,14 +353,18 @@ export default class SaleInvoicesController extends BaseController{
* @param {Response} res
* @param {Function} next
*/
async deleteSaleInvoice(req: Request, res: Response) {
async deleteSaleInvoice(req: Request, res: Response, next: NextFunction) {
const { id: saleInvoiceId } = req.params;
const { tenantId } = req;
// Deletes the sale invoice with associated entries and journal transaction.
await this.saleInvoiceService.deleteSaleInvoice(tenantId, saleInvoiceId);
return res.status(200).send({ id: saleInvoiceId });
try {
// Deletes the sale invoice with associated entries and journal transaction.
await this.saleInvoiceService.deleteSaleInvoice(tenantId, saleInvoiceId);
return res.status(200).send({ id: saleInvoiceId });
} catch (error) {
next(error);
}
}
/**

View File

@@ -1,11 +1,12 @@
import { Router, Request, Response } from 'express';
import { check, param, query, matchedData } from 'express-validator';
import { Router, Request, Response, NextFunction } from 'express';
import { check, param, query } from 'express-validator';
import { Inject, Service } from 'typedi';
import asyncMiddleware from 'api/middleware/asyncMiddleware';
import AccountsService from 'services/Accounts/AccountsService';
import ItemsService from 'services/Items/ItemsService';
import SaleReceiptService from 'services/Sales/SalesReceipts';
import BaseController from '../BaseController';
import { ISaleReceiptDTO } from 'interfaces/SaleReceipt';
@Service()
export default class SalesReceiptsController extends BaseController{
@@ -232,20 +233,21 @@ export default class SalesReceiptsController extends BaseController{
* @param {Request} req
* @param {Response} res
*/
async newSaleReceipt(req: Request, res: Response) {
async newSaleReceipt(req: Request, res: Response, next: NextFunction) {
const { tenantId } = req;
const saleReceiptDTO: ISaleReceiptDTO = this.matchedBodyData(req);
const saleReceipt = matchedData(req, {
locations: ['body'],
includeOptionals: true,
});
// Store the given sale receipt details with associated entries.
const storedSaleReceipt = await this.saleReceiptService
.createSaleReceipt(
tenantId,
saleReceipt,
);
return res.status(200).send({ id: storedSaleReceipt.id });
try {
// Store the given sale receipt details with associated entries.
const storedSaleReceipt = await this.saleReceiptService
.createSaleReceipt(
tenantId,
saleReceiptDTO,
);
return res.status(200).send({ id: storedSaleReceipt.id });
} catch (error) {
next(error);
}
}
/**
@@ -253,14 +255,18 @@ export default class SalesReceiptsController extends BaseController{
* @param {Request} req
* @param {Response} res
*/
async deleteSaleReceipt(req: Request, res: Response) {
async deleteSaleReceipt(req: Request, res: Response, next: NextFunction) {
const { tenantId } = req;
const { id: saleReceiptId } = req.params;
// Deletes the sale receipt.
await this.saleReceiptService.deleteSaleReceipt(tenantId, saleReceiptId);
return res.status(200).send({ id: saleReceiptId });
try {
// Deletes the sale receipt.
await this.saleReceiptService.deleteSaleReceipt(tenantId, saleReceiptId);
return res.status(200).send({ id: saleReceiptId });
} catch (error) {
next(error);
}
}
/**
@@ -269,25 +275,22 @@ export default class SalesReceiptsController extends BaseController{
* @param {Request} req
* @param {Response} res
*/
async editSaleReceipt(req: Request, res: Response) {
async editSaleReceipt(req: Request, res: Response, next: NextFunction) {
const { tenantId } = req;
const { id: saleReceiptId } = req.params;
const saleReceipt = { ...req.body };
const errorReasons = [];
// Handle all errors with reasons messages.
if (errorReasons.length > 0) {
return res.boom.badRequest(null, { errors: errorReasons });
}
// Update the given sale receipt details.
await this.saleReceiptService.editSaleReceipt(
tenantId,
saleReceiptId,
saleReceipt,
);
return res.status(200).send();
try {
// Update the given sale receipt details.
await this.saleReceiptService.editSaleReceipt(
tenantId,
saleReceiptId,
saleReceipt,
);
return res.status(200).send();
} catch (error) {
next(error);
}
}
/**