mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-20 23:00:34 +00:00
fix: bugs in sales estimates.
This commit is contained in:
@@ -230,37 +230,47 @@ export default class SalesEstimatesController extends BaseController {
|
|||||||
if (error instanceof ServiceError) {
|
if (error instanceof ServiceError) {
|
||||||
if (error.errorType === 'ITEMS_NOT_FOUND') {
|
if (error.errorType === 'ITEMS_NOT_FOUND') {
|
||||||
return res.boom.badRequest(null, {
|
return res.boom.badRequest(null, {
|
||||||
errors: [{ type: 'ITEMS.IDS.NOT.EXISTS', code: 400 }],
|
errors: [{ type: 'ITEMS.IDS.NOT.EXISTS', code: 100 }],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (error.errorType === 'ENTRIES_IDS_NOT_FOUND') {
|
if (error.errorType === 'ENTRIES_IDS_NOT_FOUND') {
|
||||||
return res.boom.badRequest(null, {
|
return res.boom.badRequest(null, {
|
||||||
errors: [{ type: 'ENTRIES.IDS.NOT.EXISTS', code: 300 }],
|
errors: [{ type: 'ENTRIES.IDS.NOT.EXISTS', code: 200 }],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (error.errorType === 'ITEMS_IDS_NOT_EXISTS') {
|
if (error.errorType === 'ITEMS_IDS_NOT_EXISTS') {
|
||||||
return res.boom.badRequest(null, {
|
return res.boom.badRequest(null, {
|
||||||
errors: [{ type: 'ITEMS.IDS.NOT.EXISTS', code: 200 }],
|
errors: [{ type: 'ITEMS.IDS.NOT.EXISTS', code: 300 }],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (error.errorType === 'NOT_PURCHASE_ABLE_ITEMS') {
|
if (error.errorType === 'NOT_PURCHASE_ABLE_ITEMS') {
|
||||||
return res.boom.badRequest(null, {
|
return res.boom.badRequest(null, {
|
||||||
errors: [{ type: 'NOT_PURCHASABLE_ITEMS', code: 200 }],
|
errors: [{ type: 'NOT_PURCHASABLE_ITEMS', code: 400 }],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (error.errorType === 'SALE_ESTIMATE_NOT_FOUND') {
|
if (error.errorType === 'SALE_ESTIMATE_NOT_FOUND') {
|
||||||
return res.boom.badRequest(null, {
|
return res.boom.badRequest(null, {
|
||||||
errors: [{ type: 'SALE_ESTIMATE_NOT_FOUND', code: 200 }],
|
errors: [{ type: 'SALE_ESTIMATE_NOT_FOUND', code: 500 }],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (error.errorType === 'CUSTOMER_NOT_FOUND') {
|
if (error.errorType === 'CUSTOMER_NOT_FOUND') {
|
||||||
return res.boom.badRequest(null, {
|
return res.boom.badRequest(null, {
|
||||||
errors: [{ type: 'CUSTOMER_NOT_FOUND', code: 200 }],
|
errors: [{ type: 'CUSTOMER_NOT_FOUND', code: 600 }],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (error.errorType === 'SALE_ESTIMATE_NUMBER_EXISTANCE') {
|
if (error.errorType === 'SALE_ESTIMATE_NUMBER_EXISTANCE') {
|
||||||
return res.boom.badRequest(null, {
|
return res.boom.badRequest(null, {
|
||||||
errors: [{ type: 'ESTIMATE.NUMBER.IS.NOT.UNQIUE', code: 300 }],
|
errors: [{ type: 'ESTIMATE.NUMBER.IS.NOT.UNQIUE', code: 700 }],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (error.errorType === 'NOT_SELL_ABLE_ITEMS') {
|
||||||
|
return res.boom.badRequest(null, {
|
||||||
|
errors: [{ type: 'NOT_SELL_ABLE_ITEMS', code: 800 }],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (error.errorType === 'contact_not_found') {
|
||||||
|
return res.boom.badRequest(null, {
|
||||||
|
errors: [{ type: 'CUSTOMER_NOT_FOUND', code: 900 }],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ const ERRORS = {
|
|||||||
CUSTOMER_NOT_FOUND: 'CUSTOMER_NOT_FOUND',
|
CUSTOMER_NOT_FOUND: 'CUSTOMER_NOT_FOUND',
|
||||||
SALE_ESTIMATE_NUMBER_EXISTANCE: 'SALE_ESTIMATE_NUMBER_EXISTANCE',
|
SALE_ESTIMATE_NUMBER_EXISTANCE: 'SALE_ESTIMATE_NUMBER_EXISTANCE',
|
||||||
ITEMS_IDS_NOT_EXISTS: 'ITEMS_IDS_NOT_EXISTS',
|
ITEMS_IDS_NOT_EXISTS: 'ITEMS_IDS_NOT_EXISTS',
|
||||||
}
|
};
|
||||||
/**
|
/**
|
||||||
* Sale estimate service.
|
* Sale estimate service.
|
||||||
* @Service
|
* @Service
|
||||||
@@ -97,14 +97,21 @@ export default class SaleEstimateService {
|
|||||||
amount,
|
amount,
|
||||||
...formatDateFields(estimateDTO, ['estimate_date', 'expiration_date']),
|
...formatDateFields(estimateDTO, ['estimate_date', 'expiration_date']),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Validate estimate number uniquiness on the storage.
|
||||||
await this.validateEstimateNumberExistance(tenantId, estimateDTO.estimateNumber);
|
await this.validateEstimateNumberExistance(tenantId, estimateDTO.estimateNumber);
|
||||||
|
|
||||||
|
// Retrieve the given customer or throw not found service error.
|
||||||
await this.customersService.getCustomer(tenantId, estimateDTO.customerId);
|
await this.customersService.getCustomer(tenantId, estimateDTO.customerId);
|
||||||
|
|
||||||
|
// Validate items IDs existance on the storage.
|
||||||
await this.itemsEntriesService.validateItemsIdsExistance(tenantId, estimateDTO.entries);
|
await this.itemsEntriesService.validateItemsIdsExistance(tenantId, estimateDTO.entries);
|
||||||
|
|
||||||
|
// Validate non-sellable items.
|
||||||
await this.itemsEntriesService.validateNonSellableEntriesItems(tenantId, estimateDTO.entries);
|
await this.itemsEntriesService.validateNonSellableEntriesItems(tenantId, estimateDTO.entries);
|
||||||
|
|
||||||
const saleEstimate = await SaleEstimate.query()
|
const saleEstimate = await SaleEstimate.query()
|
||||||
.upsertGraph({
|
.upsertGraphAndFetch({
|
||||||
...omit(estimateObj, ['entries']),
|
...omit(estimateObj, ['entries']),
|
||||||
entries: estimateObj.entries.map((entry) => ({
|
entries: estimateObj.entries.map((entry) => ({
|
||||||
reference_type: 'SaleEstimate',
|
reference_type: 'SaleEstimate',
|
||||||
@@ -135,19 +142,29 @@ export default class SaleEstimateService {
|
|||||||
amount,
|
amount,
|
||||||
...formatDateFields(estimateDTO, ['estimate_date', 'expiration_date']),
|
...formatDateFields(estimateDTO, ['estimate_date', 'expiration_date']),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Validate estimate number uniquiness on the storage.
|
||||||
await this.validateEstimateNumberExistance(tenantId, estimateDTO.estimateNumber, estimateId);
|
await this.validateEstimateNumberExistance(tenantId, estimateDTO.estimateNumber, estimateId);
|
||||||
|
|
||||||
|
// Retrieve the given customer or throw not found service error.
|
||||||
await this.customersService.getCustomer(tenantId, estimateDTO.customerId);
|
await this.customersService.getCustomer(tenantId, estimateDTO.customerId);
|
||||||
|
|
||||||
|
// Validate sale estimate entries existance.
|
||||||
await this.itemsEntriesService.validateEntriesIdsExistance(tenantId, estimateId, 'SaleEstiamte', estimateDTO.entries);
|
await this.itemsEntriesService.validateEntriesIdsExistance(tenantId, estimateId, 'SaleEstiamte', estimateDTO.entries);
|
||||||
|
|
||||||
|
// Validate items IDs existance on the storage.
|
||||||
await this.itemsEntriesService.validateItemsIdsExistance(tenantId, estimateDTO.entries);
|
await this.itemsEntriesService.validateItemsIdsExistance(tenantId, estimateDTO.entries);
|
||||||
|
|
||||||
|
// Validate non-sellable items.
|
||||||
await this.itemsEntriesService.validateNonSellableEntriesItems(tenantId, estimateDTO.entries);
|
await this.itemsEntriesService.validateNonSellableEntriesItems(tenantId, estimateDTO.entries);
|
||||||
|
|
||||||
this.logger.info('[sale_estimate] editing sale estimate on the storage.');
|
this.logger.info('[sale_estimate] editing sale estimate on the storage.');
|
||||||
const saleEstimate = await SaleEstimate.query()
|
const saleEstimate = await SaleEstimate.query()
|
||||||
.upsertGraph({
|
.upsertGraphAndFetch({
|
||||||
id: estimateId,
|
id: estimateId,
|
||||||
...omit(estimateObj, ['entries']),
|
...omit(estimateObj, ['entries']),
|
||||||
entries: estimateObj.entries.map((entry) => ({
|
entries: estimateObj.entries.map((entry) => ({
|
||||||
|
reference_type: 'SaleEstimate',
|
||||||
...omit(entry, ['total', 'amount']),
|
...omit(entry, ['total', 'amount']),
|
||||||
})),
|
})),
|
||||||
});
|
});
|
||||||
@@ -155,6 +172,8 @@ export default class SaleEstimateService {
|
|||||||
await this.eventDispatcher.dispatch(events.saleEstimates.onEdited, {
|
await this.eventDispatcher.dispatch(events.saleEstimates.onEdited, {
|
||||||
tenantId, estimateId, saleEstimate, oldSaleEstimate,
|
tenantId, estimateId, saleEstimate, oldSaleEstimate,
|
||||||
});
|
});
|
||||||
|
this.logger.info('[sale_estiamte] edited successfully', { tenantId, estimateId });
|
||||||
|
|
||||||
return saleEstimate;
|
return saleEstimate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,6 +187,7 @@ export default class SaleEstimateService {
|
|||||||
public async deleteEstimate(tenantId: number, estimateId: number): Promise<void> {
|
public async deleteEstimate(tenantId: number, estimateId: number): Promise<void> {
|
||||||
const { SaleEstimate, ItemEntry } = this.tenancy.models(tenantId);
|
const { SaleEstimate, ItemEntry } = this.tenancy.models(tenantId);
|
||||||
|
|
||||||
|
// Retrieve sale estimate or throw not found service error.
|
||||||
const oldSaleEstimate = await this.getSaleEstimateOrThrowError(tenantId, estimateId);
|
const oldSaleEstimate = await this.getSaleEstimateOrThrowError(tenantId, estimateId);
|
||||||
|
|
||||||
this.logger.info('[sale_estimate] delete sale estimate and associated entries from the storage.');
|
this.logger.info('[sale_estimate] delete sale estimate and associated entries from the storage.');
|
||||||
|
|||||||
Reference in New Issue
Block a user