import { uniqBy } from 'lodash'; import { getCustomRepository } from 'typeorm'; import { RawRetailerDataV1 } from '@/entities/RawRetailerProduct/types'; import { AggregateProductRepository, AggregateProductVariantRepository, RetailerProductVariantRepository, } from '@/repositories'; import { getVariantIdentifiersFromData } from '@/repositories/shared/identifiers'; import { syncProductsToAlgolia } from '@/utils'; import { CSVProduct } from './types'; const getIdentifiers = (csvProduct: CSVProduct) => { let variantIdentifiers: string[]; try { variantIdentifiers = getVariantIdentifiersFromData({ retailer: csvProduct.retailer, url: csvProduct.url, }); } catch (e) { variantIdentifiers = [ ...(csvProduct.colorCode ? [`variant:${csvProduct.colorCode}`] : []), ...(csvProduct.dimensions ? [`variant:${csvProduct.dimensions}`] : []), ]; } variantIdentifiers = variantIdentifiers .filter((id) => id !== 'unknown') .concat([`variantid:${csvProduct.variantId}`]); // variantId uniquely identifies each variant return { variantIdentifiers, productIdentifiers: [csvProduct.productId], }; }; /** * 1. Extract all unique aggregate products from the csv and save them while * preserving their ids. * 2. Save all aggregated product variants while saving preserving their ids. * 3. Once the aggregate products and variants are saved, bulk upsert all the * products from the bottom up. */ export const seedAggregateProducts = async ( csvProducts: CSVProduct[] ): Promise => { await getCustomRepository(AggregateProductRepository).bulkUpsert( uniqBy(csvProducts, 'productId').map((product) => { return { data: { ...product, pid: product.productId, isAvailable: product.availability, imageUrls: product.img ? [product.img] : [], }, identifiers: [product.productId], }; }) ); await getCustomRepository(AggregateProductVariantRepository).bulkUpsert( csvProducts.map((csvProduct) => { const { productIdentifiers, variantIdentifiers } = getIdentifiers(csvProduct); return { data: { ...csvProduct, vid: csvProduct.variantId, isAvailable: csvProduct.availability, imageUrls: csvProduct.img ? [csvProduct.img] : [], }, productIdentifiers, variantIdentifiers, }; }) ); const { aggregateProductIds } = await getCustomRepository( RetailerProductVariantRepository ).bulkUpsert({ data: csvProducts.map((csvProduct) => { const data: RawRetailerDataV1 = { price: csvProduct.price || 0, url: csvProduct.url || '', asin: csvProduct.asin, colorCode: csvProduct.colorCode, dimensions: csvProduct.dimensions, imageUrls: csvProduct.img ? [csvProduct.img] : [], name: csvProduct.name, isAvailable: csvProduct.availability, distributorSKU: csvProduct.distributorSKU, distributor: csvProduct.distributor, }; const { productIdentifiers, variantIdentifiers } = getIdentifiers(csvProduct); return { data, productIdentifiers, variantIdentifiers, retailer: csvProduct.retailer, }; }), }); return syncProductsToAlgolia(aggregateProductIds); };