fix: convert sale estimate to invoice.

This commit is contained in:
a.bouhuolia
2021-02-28 15:26:23 +02:00
parent fb9d68c2cf
commit 4d751f772e
6 changed files with 47 additions and 12 deletions

View File

@@ -7,7 +7,6 @@ import asyncMiddleware from 'api/middleware/asyncMiddleware';
import SaleEstimateService from 'services/Sales/SalesEstimate'; import SaleEstimateService from 'services/Sales/SalesEstimate';
import DynamicListingService from 'services/DynamicListing/DynamicListService'; import DynamicListingService from 'services/DynamicListing/DynamicListService';
import { ServiceError } from "exceptions"; import { ServiceError } from "exceptions";
import { Request } from 'express-validator/src/base';
@Service() @Service()
export default class SalesEstimatesController extends BaseController { export default class SalesEstimatesController extends BaseController {

View File

@@ -400,6 +400,20 @@ export default class SaleInvoicesController extends BaseController {
], ],
}); });
} }
if (error.errorType === 'SALE_ESTIMATE_NOT_FOUND') {
return res.boom.badRequest(null, {
errors: [
{ type: 'FROM_SALE_ESTIMATE_NOT_FOUND', code: 1200 },
],
});
}
if (error.errorType === 'SALE_ESTIMATE_CONVERTED_TO_INVOICE') {
return res.boom.badRequest(null, {
errors: [
{ type: 'SALE_ESTIMATE_IS_ALREADY_CONVERTED_TO_INVOICE', code: 1300 },
],
});
}
} }
next(error); next(error);
} }

View File

@@ -14,6 +14,7 @@ export interface ISaleEstimate {
sendToEmail: string, sendToEmail: string,
createdAt?: Date, createdAt?: Date,
deliveredAt: string|Date, deliveredAt: string|Date,
isConvertedToInvoice: boolean
}; };
export interface ISaleEstimateDTO { export interface ISaleEstimateDTO {
customerId: number, customerId: number,

View File

@@ -98,6 +98,16 @@ export default class SaleEstimateService {
} }
} }
/**
* Validates the given sale estimate not already converted to invoice.
* @param {ISaleEstimate} saleEstimate -
*/
validateEstimateNotConverted(saleEstimate: ISaleEstimate) {
if (saleEstimate.isConvertedToInvoice) {
throw new ServiceError(ERRORS.SALE_ESTIMATE_CONVERTED_TO_INVOICE);
}
}
/** /**
* Transform DTO object ot model object. * Transform DTO object ot model object.
* @param {number} tenantId * @param {number} tenantId
@@ -181,6 +191,7 @@ export default class SaleEstimateService {
tenantId, tenantId,
saleEstimate, saleEstimate,
saleEstimateId: saleEstimate.id, saleEstimateId: saleEstimate.id,
saleEstimateDTO: estimateDTO,
}); });
return saleEstimate; return saleEstimate;

View File

@@ -165,10 +165,10 @@ export default class SaleInvoicesService {
); );
return { return {
...formatDateFields(omit(saleInvoiceDTO, ['delivered', 'entries']), [ ...formatDateFields(
'invoiceDate', omit(saleInvoiceDTO, ['delivered', 'entries', 'fromEstimateId']),
'dueDate', ['invoiceDate', 'dueDate']
]), ),
// Avoid rewrite the deliver date in edit mode when already published. // Avoid rewrite the deliver date in edit mode when already published.
...(saleInvoiceDTO.delivered && ...(saleInvoiceDTO.delivered &&
!oldSaleInvoice?.deliveredAt && { !oldSaleInvoice?.deliveredAt && {
@@ -213,6 +213,15 @@ export default class SaleInvoicesService {
saleInvoiceDTO.invoiceNo saleInvoiceDTO.invoiceNo
); );
} }
// Validate the from estimate id exists on the storage.
if (saleInvoiceDTO.fromEstimateId) {
const fromEstimate = await this.saleEstimatesService.getSaleEstimateOrThrowError(
tenantId,
saleInvoiceDTO.fromEstimateId
);
// Validate the sale estimate is not already converted to invoice.
this.saleEstimatesService.validateEstimateNotConverted(fromEstimate);
}
// Validate items ids existance. // Validate items ids existance.
await this.itemsEntriesService.validateItemsIdsExistance( await this.itemsEntriesService.validateItemsIdsExistance(
tenantId, tenantId,
@@ -232,6 +241,7 @@ export default class SaleInvoicesService {
await this.eventDispatcher.dispatch(events.saleInvoice.onCreated, { await this.eventDispatcher.dispatch(events.saleInvoice.onCreated, {
tenantId, tenantId,
saleInvoice, saleInvoice,
saleInvoiceDTO,
saleInvoiceId: saleInvoice.id, saleInvoiceId: saleInvoice.id,
authorizedUser, authorizedUser,
}); });
@@ -503,8 +513,8 @@ export default class SaleInvoicesService {
/** /**
* Retrieve sale invoice with associated entries. * Retrieve sale invoice with associated entries.
* @param {Number} saleInvoiceId - * @param {Number} saleInvoiceId -
* @param {ISystemUser} authorizedUser - * @param {ISystemUser} authorizedUser -
* @return {Promise<ISaleInvoice>} * @return {Promise<ISaleInvoice>}
*/ */
public async getSaleInvoice( public async getSaleInvoice(
@@ -584,7 +594,6 @@ export default class SaleInvoicesService {
} }
}); });
return salesInvoices; return salesInvoices;
} }
} }

View File

@@ -26,15 +26,16 @@ export default class SaleInvoiceSubscriber {
* Marks the sale estimate as converted from the sale invoice once created. * Marks the sale estimate as converted from the sale invoice once created.
*/ */
@On(events.saleInvoice.onCreated) @On(events.saleInvoice.onCreated)
public async handleMarkEstimateConvert({ public async handleMarkEstimateConvertOnceInvoiceCreated({
tenantId, tenantId,
saleInvoice, saleInvoice,
saleInvoiceDTO,
saleInvoiceId, saleInvoiceId,
}) { }) {
if (saleInvoice.fromEstimateId) { if (saleInvoiceDTO.fromEstimateId) {
this.saleEstimatesService.convertEstimateToInvoice( await this.saleEstimatesService.convertEstimateToInvoice(
tenantId, tenantId,
saleInvoice.fromEstiamteId, saleInvoiceDTO.fromEstimateId,
saleInvoiceId saleInvoiceId
); );
} }