import { union } from 'lodash'; import { AbstractRepository, EntityManager, EntityRepository, getCustomRepository, getManager, } from 'typeorm'; import { RawGoogleShoppingOffers } from '@/entities'; import { RawGoogleShoppingOffersDataV1 } from '@/entities/RawGoogleShoppingOffers/types'; import { RetailerProductSource } from '@/entities/types'; import { RetailerKind } from '@/types'; import { syncProductsToAlgolia } from '@/utils'; import { getRetailerFromUrl } from '@/utils/retailer'; import { RetailerProductVariantRepository } from '..'; import { getProductIdentifiersFromData, getVariantIdentifiersFromData, } from '../shared/identifiers'; /** * Repository for the RawGoogleShoppingOffers entity. */ @EntityRepository(RawGoogleShoppingOffers) // eslint-disable-next-line max-len export default class RawGoogleShoppingOffersRepository extends AbstractRepository { /** * Creates a raw google shopping product in the db. */ async create( { googleShoppingId, data, ingestionID, productIds, }: { googleShoppingId: string; data: RawGoogleShoppingOffersDataV1; ingestionID?: string; productIds?: string[]; }, manager: EntityManager = getManager() ): Promise { if (data.offers.length === 0) { throw new Error('Cannot store google shopping offers with no offers.'); } const googleShoppingIdentifer = `googleshoppingid:${googleShoppingId}`; const offersData = data.offers.map((offer) => { const retailer = getRetailerFromUrl(offer.url); return { retailer, productIdentifiers: union([ ...getProductIdentifiersFromData({ url: offer.url, retailer, }), ...(productIds ?? []), ]), variantIdentifiers: [ googleShoppingIdentifer, ...(ingestionID ? [`ingestionid:${ingestionID}`] : []), ...(retailer in RetailerKind ? getVariantIdentifiersFromData({ url: offer.url, retailer: retailer as RetailerKind, }) : []), ], data: { price: offer.price, url: offer.url, }, }; }); const { aggregateProductIds } = await getCustomRepository( RetailerProductVariantRepository ).bulkUpsert( { data: offersData, source: RetailerProductSource.GOOGLE_OFFERS }, manager ); const result = await manager.save( RawGoogleShoppingOffers, manager.create(RawGoogleShoppingOffers, { googleShoppingId, rawData: data, }) ); await syncProductsToAlgolia(aggregateProductIds); return result; } }