try {
const { tradingPartnerId } = request.params;
let { barcode, skip, limit, search, colorFilter, sizeFilter, sortDirection, sortField } = request.query;
if (!await verifyId(request, tradingPartnerId, next)) return
let query = { tradingpartner: tradingPartnerId , type: 'simple' }
if (!skip) skip = 0;
if (!limit) limit = 10;
if (barcode) query = Object.assign(query, { barcode })
/** Filter by name and barcode */
if (search)
query = Object.assign(query, {
$or: [{ 'info.name': new RegExp(search, 'i') }, { 'barcode': new RegExp(search, 'i') }]
})
if (!sortField || sortField === 'name') sortField = 'info.name'
!sortDirection || sortDirection === 'asc' ? sortDirection = 1 : sortDirection = -1
/* Get all products attribute details */
const allProductSizeList: string[] = [], allProductColorList: string[] = [];
const productAttributesList = await AttributeModel.find({ tradingPartner: tradingPartnerId })
const allAttributeIdList: any[] = [], allValueIdList: any [] = [];
await mapLimit(productAttributesList, 10, async (ao: any) => {
if (!ao.title || !ao.values.length) return;
if (ao.title.toLowerCase() === 'color') {
await ao.values.map((item: any) => {
if (colorFilter && item.title === colorFilter) {
if (allAttributeIdList.indexOf(ao.attributeId) === -1) allAttributeIdList.push(ao.attributeId)
if (allValueIdList.indexOf(item.valueId) === -1) allValueIdList.push(item.valueId)
}
if (allProductColorList.indexOf(item.title) === -1) allProductColorList.push(item.title)
})
}
if (ao.attributeId.toLowerCase() === 'size') {
await ao.values.map((item: any) => {
if (sizeFilter && item.title === sizeFilter) {
if (allAttributeIdList.indexOf(ao.attributeId) === -1) allAttributeIdList.push(ao.attributeId)
if (allValueIdList.indexOf(item.valueId) === -1) allValueIdList.push(item.valueId)
}
if (allProductSizeList.indexOf(item.title) === -1) allProductSizeList.push(item.title)
})
}
})
/** Filter by color */
if (colorFilter || sizeFilter)
query = Object.assign(query, { 'attributeOption.attributeId': { $in: allAttributeIdList }, 'attributeOption.valueId': { $in: allValueIdList } })
const productList: any = await ProductModel.find(query).sort({ [sortField]: sortDirection }).lean().exec();
/** Prepare productList with stocks, lastUpdateDate, size, color, etc */
const traversedProductList: any[] = await mapLimit(productList, 10, async (oneProduct: any) => {
/** Latest internalInventorylist */
const internalInventoryList: any = await InventoryEventModel.find({
tradingPartnerId: oneProduct.tradingpartner,
productEAN: oneProduct.barcode
}).select('storeExternalId amount occurred -_id').sort({ occurred: 'desc' }).lean().exec();
/** Last update date */
const latestInventoryUpdate: any = internalInventoryList.length && internalInventoryList[0].occurred ? internalInventoryList[0].occurred : null;
let attributeList: any[] = [];
/** Prepare AttributeList by product Attributes */
await mapLimit(oneProduct.attributeOption, 1, async (ao: any) => {
if (!ao.attributeId && !ao.valueId) return;
const attributeDetails: any = productAttributesList.find((oneAttribute: any) =>
oneAttribute.attributeId === ao.attributeId &&
oneAttribute.values.filter((oneValue: any) => oneValue.valueId === ao.valueId).length > 0
)
if (!attributeDetails || !attributeDetails.title) return;
if (['size', 'color'].indexOf(attributeDetails.title.toLowerCase()) === -1) return;
const attributeValueDetails: any = await attributeDetails.values.find((oneValue: any) => oneValue.valueId === ao.valueId)
if (!attributeValueDetails || !attributeValueDetails.title) return;
const existingAttribute: any = attributeList.find((a: any) => a.type && a.type === String(attributeDetails.title).toLowerCase() ? true : false)
if (!existingAttribute)
attributeList = [...attributeList, { type: String(attributeDetails.title).toLowerCase(), value: attributeValueDetails.title }]
})
// let isAttributeMatch: boolean = false;
// /** Filter by size and color */
// if (sizeFilter && colorFilter)
// isAttributeMatch = attributeList.filter((oneAttribute: any) =>
// (
// String(oneAttribute.type).toLowerCase() === 'size' &&
// oneAttribute.value === sizeFilter &&
// attributeList.filter((oneAttr: any) => oneAttr.type === 'color' && oneAttr.value === colorFilter).length > 0
// ) ? true : false
// ).length > 0 ? true : false
// /** Filter by size */
// if (sizeFilter && !colorFilter)
// isAttributeMatch = attributeList.filter((oneAttribute: any) => oneAttribute.type === 'size' && oneAttribute.value === sizeFilter).length > 0 ? true : false
// /** Filter by color */
// if (colorFilter && !sizeFilter)
// isAttributeMatch = attributeList.filter((oneAttribute: any) => oneAttribute.type === 'color' && oneAttribute.value === colorFilter).length > 0 ? true : false
// if (!isAttributeMatch) return true;
/** Get externalInventory */
const externalInventoryResponse: any = await ourTradeHubApi.getExternalStockList(oneProduct.tradingpartner, barcode)
let externalStockList: any = []
let totalExternalStock: number = 0
/** Prepare externalStockList and totalExternalStock by externalInventory */
if (externalInventoryResponse && externalInventoryResponse.data) {
externalStockList = externalInventoryResponse.data.history.length ? externalInventoryResponse.data.history : []
totalExternalStock = externalInventoryResponse.data.currentTotal ? externalInventoryResponse.data.currentTotal : 0
}
await externalStockList.map((stockDetails: any) => delete stockDetails.updates)
return {
_id: oneProduct._id,
attributes: attributeList,
barcode: oneProduct.barcode,
categories: await mapLimit(oneProduct.categories, 1, async (oneCat: any) => {
const categoryDetails: any = await CategoryModel.findOne({ categoryId: oneCat }).exec();
if (!categoryDetails) return;
let categoryPath: string = ''
if (categoryDetails && categoryDetails.parentId) {
categoryPath = await getCategoryFullPath(categoryDetails.parentId, []) + '/' + categoryDetails.name || ''
} else {
categoryPath = categoryDetails.name || ''
}
return categoryPath
}),
description: oneProduct.info.description || '',
images: oneProduct.info.image || [],
internalStockList: internalInventoryList,
externalStockList,
itemNumber: oneProduct.info.itemnumber || '',
latestInventoryUpdate,
name: oneProduct.info.name || '',
price: oneProduct.prices.length && oneProduct.prices[0].value ? oneProduct.prices[0].value : 0,
priceCurrency: oneProduct.prices.length && oneProduct.prices[0].currency ? oneProduct.prices[0].currency : '',
totalExternalStock,
totalInternalStock: internalInventoryList.reduce((previews: any, current: any) => previews + current.amount, 0)
}
})
const totalProductCount: number = await ProductModel.count(query);
response.send({ colors: allProductColorList, sizes: allProductSizeList, length: totalProductCount, products: traversedProductList.slice(skip, skip + limit) });
} catch (error) {
response.status(400).send(error.message + error);
}
})
0 Comments