WIP: allocate landed cost.

This commit is contained in:
a.bouhuolia
2021-07-24 03:46:25 +02:00
parent ca48dac75d
commit 504b380da6
5 changed files with 69 additions and 19 deletions

View File

@@ -446,7 +446,9 @@ export default class BillsController extends BaseController {
], ],
}); });
} }
if (error.errorType === 'LOCATED_COST_ENTRIES_SHOULD_BIGGE_THAN_NEW_ENTRIES') { if (
error.errorType === 'LOCATED_COST_ENTRIES_SHOULD_BIGGE_THAN_NEW_ENTRIES'
) {
return res.status(400).send({ return res.status(400).send({
errors: [ errors: [
{ {
@@ -456,6 +458,18 @@ export default class BillsController extends BaseController {
], ],
}); });
} }
if (error.errorType === 'LANDED_COST_ENTRIES_SHOULD_BE_INVENTORY_ITEMS') {
return res.status(400).send({
errors: [
{
type: 'LANDED_COST_ENTRIES_SHOULD_BE_INVENTORY_ITEMS',
message:
'Landed cost entries should be only with inventory items.',
code: 1600,
},
],
});
}
} }
next(error); next(error);
} }

View File

@@ -25,5 +25,6 @@ export interface IItemEntry {
export interface IItemEntryDTO { export interface IItemEntryDTO {
id?: number, id?: number,
itemId: number;
landedCost?: boolean; landedCost?: boolean;
} }

View File

@@ -17,16 +17,16 @@ const ERRORS = {
export default class EntriesService { export default class EntriesService {
/** /**
* Validates bill entries that has allocated landed cost amount not deleted. * Validates bill entries that has allocated landed cost amount not deleted.
* @param {IItemEntry[]} oldBillEntries - * @param {IItemEntry[]} oldCommonEntries -
* @param {IItemEntry[]} newBillEntries - * @param {IItemEntry[]} newBillEntries -
*/ */
public getLandedCostEntriesDeleted( public getLandedCostEntriesDeleted(
oldBillEntries: ICommonLandedCostEntry[], oldCommonEntries: ICommonLandedCostEntry[],
newBillEntriesDTO: ICommonLandedCostEntryDTO[] newCommonEntriesDTO: ICommonLandedCostEntryDTO[]
): ICommonLandedCostEntry[] { ): ICommonLandedCostEntry[] {
const newBillEntriesById = transformToMap(newBillEntriesDTO, 'id'); const newBillEntriesById = transformToMap(newCommonEntriesDTO, 'id');
return oldBillEntries.filter((entry) => { return oldCommonEntries.filter((entry) => {
const newEntry = newBillEntriesById.get(entry.id); const newEntry = newBillEntriesById.get(entry.id);
if (entry.allocatedCostAmount > 0 && typeof newEntry === 'undefined') { if (entry.allocatedCostAmount > 0 && typeof newEntry === 'undefined') {
@@ -38,16 +38,16 @@ export default class EntriesService {
/** /**
* Validates the bill entries that have located cost amount should not be deleted. * Validates the bill entries that have located cost amount should not be deleted.
* @param {IItemEntry[]} oldBillEntries - Old bill entries. * @param {IItemEntry[]} oldCommonEntries - Old bill entries.
* @param {IItemEntryDTO[]} newBillEntries - New DTO bill entries. * @param {IItemEntryDTO[]} newBillEntries - New DTO bill entries.
*/ */
public validateLandedCostEntriesNotDeleted( public validateLandedCostEntriesNotDeleted(
oldBillEntries: ICommonLandedCostEntry[], oldCommonEntries: ICommonLandedCostEntry[],
newBillEntriesDTO: ICommonLandedCostEntryDTO[] newCommonEntriesDTO: ICommonLandedCostEntryDTO[]
): void { ): void {
const entriesDeleted = this.getLandedCostEntriesDeleted( const entriesDeleted = this.getLandedCostEntriesDeleted(
oldBillEntries, oldCommonEntries,
newBillEntriesDTO newCommonEntriesDTO
); );
if (entriesDeleted.length > 0) { if (entriesDeleted.length > 0) {
throw new ServiceError(ERRORS.ENTRIES_ALLOCATED_COST_COULD_NOT_DELETED); throw new ServiceError(ERRORS.ENTRIES_ALLOCATED_COST_COULD_NOT_DELETED);
@@ -56,16 +56,16 @@ export default class EntriesService {
/** /**
* Validate allocated cost amount entries should be smaller than new entries amount. * Validate allocated cost amount entries should be smaller than new entries amount.
* @param {IItemEntry[]} oldBillEntries - Old bill entries. * @param {IItemEntry[]} oldCommonEntries - Old bill entries.
* @param {IItemEntryDTO[]} newBillEntries - New DTO bill entries. * @param {IItemEntryDTO[]} newBillEntries - New DTO bill entries.
*/ */
public validateLocatedCostEntriesSmallerThanNewEntries( public validateLocatedCostEntriesSmallerThanNewEntries(
oldBillEntries: ICommonLandedCostEntry[], oldCommonEntries: ICommonLandedCostEntry[],
newBillEntriesDTO: ICommonLandedCostEntryDTO[] newCommonEntriesDTO: ICommonLandedCostEntryDTO[]
): void { ): void {
const oldBillEntriesById = transformToMap(oldBillEntries, 'id'); const oldBillEntriesById = transformToMap(oldCommonEntries, 'id');
newBillEntriesDTO.forEach((entry) => { newCommonEntriesDTO.forEach((entry) => {
const oldEntry = oldBillEntriesById.get(entry.id); const oldEntry = oldBillEntriesById.get(entry.id);
if (oldEntry && oldEntry.allocatedCostAmount > entry.amount) { if (oldEntry && oldEntry.allocatedCostAmount > entry.amount) {

View File

@@ -13,7 +13,7 @@ import InventoryService from 'services/Inventory/Inventory';
import SalesInvoicesCost from 'services/Sales/SalesInvoicesCost'; import SalesInvoicesCost from 'services/Sales/SalesInvoicesCost';
import TenancyService from 'services/Tenancy/TenancyService'; import TenancyService from 'services/Tenancy/TenancyService';
import DynamicListingService from 'services/DynamicListing/DynamicListService'; import DynamicListingService from 'services/DynamicListing/DynamicListService';
import { formatDateFields } from 'utils'; import { formatDateFields, transformToMap } from 'utils';
import { import {
IBillDTO, IBillDTO,
IBill, IBill,
@@ -194,6 +194,36 @@ export default class BillsService
} }
} }
/**
* Validate transaction entries that have landed cost type should not be
* inventory items.
* @param {number} tenantId -
* @param {IItemEntryDTO[]} newEntriesDTO -
*/
public async validateCostEntriesShouldBeInventoryItems(
tenantId: number,
newEntriesDTO: IItemEntryDTO[]
) {
const { Item } = this.tenancy.models(tenantId);
const entriesItemsIds = newEntriesDTO.map((e) => e.itemId);
const entriesItems = await Item.query().whereIn('id', entriesItemsIds);
const entriesItemsById = transformToMap(entriesItems, 'id');
// Filter the landed cost entries that not associated with inventory item.
const nonInventoryHasCost = newEntriesDTO.filter((entry) => {
const item = entriesItemsById.get(entry.itemId);
return entry.landedCost && item.type !== 'inventory';
});
if (nonInventoryHasCost.length > 0) {
throw new ServiceError(
ERRORS.LANDED_COST_ENTRIES_SHOULD_BE_INVENTORY_ITEMS
);
}
}
/** /**
* Sets the default cost account to the bill entries. * Sets the default cost account to the bill entries.
*/ */
@@ -334,6 +364,10 @@ export default class BillsService
tenantId, tenantId,
billDTO.entries billDTO.entries
); );
await this.validateCostEntriesShouldBeInventoryItems(
tenantId,
billDTO.entries,
);
this.logger.info('[bill] trying to create a new bill', { this.logger.info('[bill] trying to create a new bill', {
tenantId, tenantId,
billDTO, billDTO,
@@ -423,7 +457,7 @@ export default class BillsService
// Validate landed cost entries that have allocated cost could not be deleted. // Validate landed cost entries that have allocated cost could not be deleted.
await this.entriesService.validateLandedCostEntriesNotDeleted( await this.entriesService.validateLandedCostEntriesNotDeleted(
oldBill.entries, oldBill.entries,
billObj.entries, billObj.entries
); );
// Validate new landed cost entries should be bigger than new entries. // Validate new landed cost entries should be bigger than new entries.
await this.entriesService.validateLocatedCostEntriesSmallerThanNewEntries( await this.entriesService.validateLocatedCostEntriesSmallerThanNewEntries(

View File

@@ -12,5 +12,6 @@ export const ERRORS = {
VENDOR_HAS_BILLS: 'VENDOR_HAS_BILLS', VENDOR_HAS_BILLS: 'VENDOR_HAS_BILLS',
BILL_HAS_ASSOCIATED_LANDED_COSTS: 'BILL_HAS_ASSOCIATED_LANDED_COSTS', BILL_HAS_ASSOCIATED_LANDED_COSTS: 'BILL_HAS_ASSOCIATED_LANDED_COSTS',
BILL_ENTRIES_ALLOCATED_COST_COULD_DELETED: 'BILL_ENTRIES_ALLOCATED_COST_COULD_DELETED', BILL_ENTRIES_ALLOCATED_COST_COULD_DELETED: 'BILL_ENTRIES_ALLOCATED_COST_COULD_DELETED',
LOCATED_COST_ENTRIES_SHOULD_BIGGE_THAN_NEW_ENTRIES: 'LOCATED_COST_ENTRIES_SHOULD_BIGGE_THAN_NEW_ENTRIES' LOCATED_COST_ENTRIES_SHOULD_BIGGE_THAN_NEW_ENTRIES: 'LOCATED_COST_ENTRIES_SHOULD_BIGGE_THAN_NEW_ENTRIES',
LANDED_COST_ENTRIES_SHOULD_BE_INVENTORY_ITEMS: 'LANDED_COST_ENTRIES_SHOULD_BE_INVENTORY_ITEMS'
}; };