Skip to content

Commit

Permalink
Translate product properties and specs
Browse files Browse the repository at this point in the history
  • Loading branch information
thalytafabrine committed Feb 26, 2024
1 parent 4312bcc commit feec83e
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 31 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

### Added
- Translations to product query.

### Changed
- Get SKU details from SKU document when mapping search document.

Expand Down
2 changes: 1 addition & 1 deletion src/convertSKU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ const convertSKU = (product: BiggySearchProduct, indexingType?: IndexingType, tr
videos: sku.videos ?? [],
attachments: [],
isKit: false,
attributes
attributes,
}

variations.forEach((variation) => {
Expand Down
136 changes: 106 additions & 30 deletions src/convertSearchDocument.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { dateToTicks, getPriceRange, objToNameValue } from './utils'
import { dateToTicks, getPriceRange, getTranslationInfo, objToNameValue } from './utils'

interface TranslatedProperty {
field: string
context: string
translation: string
}

const searchableClustersFromDocument = (
ProductClusterNames: Record<string, string>,
Expand All @@ -13,15 +19,21 @@ const searchableClustersFromDocument = (
return searchableClusters
}

const categoriesFromDocument = (CategoriesFullPath: string[], CategoriesName: Record<string, string>) => {
const categoriesFromDocument = (
CategoriesFullPath: string[],
CategoriesName: Record<string, string>,
translations?: TranslatedProperty[]
) => {
const categories: string[] = []

CategoriesFullPath.forEach((path) => {
let categoryPath = '/'
const ids = path.split('/').filter((value) => value)

ids.forEach((id) => {
categoryPath = categoryPath.concat(`${CategoriesName[id]}/`)
const translatedName = getTranslationInfo('CategoryName', translations, id) ?? CategoriesName[id]

categoryPath = categoryPath.concat(`${translatedName}/`)
})

categories.push(categoryPath)
Expand Down Expand Up @@ -62,7 +74,10 @@ interface SpecificationInfo {
[key: string]: any
}

const specificationsInfoFromDocument = (SpecificationGroups: SkuDocumentSpecificationGroup[]): SpecificationInfo => {
const specificationsInfoFromDocument = (
SpecificationGroups: SkuDocumentSpecificationGroup[],
translations?: TranslatedProperty[]
): SpecificationInfo => {
const specificationsInfo: Record<string, any> = {}
const specificationGroups: SpecificationGroup[] = []
const properties: ProductProperty[] = []
Expand All @@ -85,22 +100,26 @@ const specificationsInfoFromDocument = (SpecificationGroups: SkuDocumentSpecific

groupSpecs
.map((specification) => ({
name: specification.Name,
originalName: specification.Name, // translate
values: specification.SpecificationValues.map((spec) => spec.Value), // translate
name: getTranslationInfo('SpecificationName', translations, specification.FieldId) ?? specification.Name,
originalName: specification.Name,
values: specification.SpecificationValues.map(
(spec) => getTranslationInfo('SpecificationValue', translations, spec.Id) ?? spec.Value
),
}))
.forEach((spec) => properties.push(spec))

const visibleSpecs = groupSpecs.filter((spec) => spec.IsOnProductDetails)

if (visibleSpecs.length) {
specificationGroups.push({
name: group.GroupName, // translate
name: group.GroupName,
originalName: group.GroupName,
specifications: visibleSpecs.map((specification) => ({
name: specification.Name,
name: getTranslationInfo('SpecificationName', translations, specification.FieldId) ?? specification.Name,
originalName: specification.Name,
values: specification.SpecificationValues.map((spec) => spec.Value), // translate
values: specification.SpecificationValues.map(
(spec) => getTranslationInfo('SpecificationValue', translations, spec.Id) ?? spec.Value
),
})),
})
}
Expand All @@ -123,6 +142,46 @@ const specificationsInfoFromDocument = (SpecificationGroups: SkuDocumentSpecific
}
}

const skuSpecificationsFromDocuments = (
allSpecGroups: SkuDocumentSpecificationGroup[][],
translations?: TranslatedProperty[]
) => {
const skuSpecs: SkuDocumentSpecification[] = []
const groupedSpecs: Record<string, { Name: string; SpecificationValues: SkuDocumentSpecificationValue[] }> = {}

allSpecGroups.flat().forEach((specGroup) => {
const skuSpecsFromGroup = specGroup.Specifications.filter((spec) => spec.Field.IsStockKeppingUnit)

if (skuSpecsFromGroup.length) {
skuSpecs.push(...skuSpecsFromGroup)
}
})

skuSpecs.forEach((specification) => {
groupedSpecs[specification.FieldId] = {
Name: specification.Name,
SpecificationValues: (groupedSpecs[specification.FieldId]?.SpecificationValues ?? []).concat(
specification.SpecificationValues
),
}
})

return Object.keys(groupedSpecs).map((key) => {
const item = groupedSpecs[key]

return {
field: {
name: getTranslationInfo('SpecificationName', translations, key) ?? item.Name,
originalName: item.Name,
},
values: item.SpecificationValues.map((value) => ({
name: getTranslationInfo('SpecificationValue', translations, value.Id) ?? value.Value,
originalName: value.Value,
})),
}
})
}

const getSpotPrice = (paymentOptions: PaymentOptions, priceWithoutDiscount: number) => {
const installments = paymentOptions.InstallmentOptions.flatMap((option) => option.Installments)
const installment = installments.find(
Expand Down Expand Up @@ -256,7 +315,8 @@ const getSkuSubscriptions = (agregatedAttachments: SkuDocumentAttachment[]) =>

const getSkuVariations = (
specificationGroups: SkuDocumentSpecificationGroup[],
attachments: SkuDocumentAttachment[]
attachments: SkuDocumentAttachment[],
translations?: TranslatedProperty[]
) => {
const attributes: Array<{
key: string
Expand All @@ -275,10 +335,9 @@ const getSkuVariations = (
filteredSpecs.forEach((spec) => {
spec.SpecificationValues.forEach((value) => {
attributes.push({
key: spec.Field.Name,
value: value.Value,
key: getTranslationInfo('SpecificationName', translations, spec.Field.Id.toString()) ?? spec.Field.Name,
value: getTranslationInfo('SpecificationValue', translations, value.Id) ?? value.Value,
})
// translate (ver text_attributes)
})
})
})
Expand All @@ -305,7 +364,12 @@ const getAttachments = (attachments: SkuDocumentAttachment[]): SearchAttachment[
}))
}

export const itemsFromSearchDocuments = (documents: SkuDocument[], offers: SkuOffers, account: string) => {
export const itemsFromSearchDocuments = (
documents: SkuDocument[],
offers: SkuOffers,
account: string,
translations?: TranslatedProperty[]
) => {
const items: SearchItem[] = []

documents.forEach((skuDocument) => {
Expand All @@ -315,14 +379,17 @@ export const itemsFromSearchDocuments = (documents: SkuDocument[], offers: SkuOf
return
}

const variations = getSkuVariations(skuDocument.SpecificationGroups, skuDocument.AgregatedAttachments)
const variations = getSkuVariations(skuDocument.SpecificationGroups, skuDocument.AgregatedAttachments, translations)
const images = convertDocumentImages(skuDocument.Images, account)
const attachments = getAttachments(skuDocument.AgregatedAttachments)
const nameComplete = `${
getTranslationInfo('ProductName', translations, skuDocument.ProductId) ?? skuDocument.ProductName
} ${getTranslationInfo('SkuName', translations, skuDocument.Id) ?? skuDocument.Name}`

const searchItem = {
itemId: skuDocument.Id,
name: skuDocument.Name,
nameComplete: skuDocument.NameComplete,
name: getTranslationInfo('SkuName', translations, skuDocument.Id) ?? skuDocument.Name,
nameComplete,
complementName: skuDocument.NameComplement,
ean: skuDocument.AlternateIds.Ean ?? '',
referenceId: [
Expand All @@ -340,7 +407,7 @@ export const itemsFromSearchDocuments = (documents: SkuDocument[], offers: SkuOf
sellers: getSkuSellers(offer, skuDocument.UnitMultiplier),
attachments,
isKit: skuDocument.IsKit,
kitItems: [], // do we need to define this prop?
kitItems: [],
}

items.push(searchItem)
Expand All @@ -349,7 +416,12 @@ export const itemsFromSearchDocuments = (documents: SkuDocument[], offers: SkuOf
return items
}

export const convertSearchDocument = async (documents: SkuDocument[], offers: SkuOffers, account: string) => {
export const convertSearchDocument = async (
documents: SkuDocument[],
offers: SkuOffers,
account: string,
translations?: TranslatedProperty[]
) => {
const [
{
ProductId,
Expand All @@ -374,10 +446,14 @@ export const convertSearchDocument = async (documents: SkuDocument[], offers: Sk

const searchableClusters = searchableClustersFromDocument(ProductClusterNames, ProductClusterSearchableIds)

const categories = categoriesFromDocument(CategoriesFullPath, CategoriesName)
// validar se só precisa pegar do primeiro item msm. talvez tenha que unir os itens
const specificationsInfo = specificationsInfoFromDocument(SpecificationGroups)
const items = itemsFromSearchDocuments(documents, offers, account)
const categories = categoriesFromDocument(CategoriesFullPath, CategoriesName, translations)
const specificationsInfo = specificationsInfoFromDocument(SpecificationGroups, translations)
const skuSpecifications = skuSpecificationsFromDocuments(
documents.map((document) => document.SpecificationGroups),
translations
)

const items = itemsFromSearchDocuments(documents, offers, account, translations)

const product: SearchProduct & {
cacheId?: string
Expand All @@ -386,14 +462,14 @@ export const convertSearchDocument = async (documents: SkuDocument[], offers: Sk
categories,
categoriesIds: CategoriesFullPath,
productId: ProductId,
productName: ProductName,
productName: getTranslationInfo('ProductName', translations) ?? ProductName,
cacheId: `sp-${ProductId}`,
productReference: ProductRefId,
linkText: LinkId, // translate
brand: BrandName,
linkText: LinkId,
brand: getTranslationInfo('BrandName', translations) ?? BrandName,
brandId: BrandId,
link: `https://portal.vtexcommercestable.com.br/${LinkId}/p`,
description: Description,
description: getTranslationInfo('Description', translations) ?? Description,
items,
priceRange: getPriceRange(items),
categoryId: DirectCategoryId.toString(),
Expand All @@ -403,8 +479,8 @@ export const convertSearchDocument = async (documents: SkuDocument[], offers: Sk
productClusters: objToNameValue('id', 'name', ProductClusterNames),
searchableClusters,
titleTag: '',
categoryTree: [], // fix
skuSpecifications: [], // fix
categoryTree: [],
skuSpecifications,
...specificationsInfo,
origin: 'search-document',
releaseDate: ReleaseDate,
Expand Down
16 changes: 16 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,19 @@ export const getPriceRange = (searchItems: SearchItem[]) => {
const TICKS_AT_EPOCH = 621355968000000000

export const dateToTicks = (dateTime: string) => (new Date(dateTime)).getTime() * 10000 + TICKS_AT_EPOCH

export const getTranslationInfo = (
info: string,
translationInfo?: Array<{ field: string; context: string; translation: string }>,
infoId?: string
) => {
if (!translationInfo || !translationInfo.length) {
return undefined
}

const item = translationInfo.find((value) =>
infoId ? value.field === info && value.context === infoId : value.field === info
)

return item ? item.translation : undefined
}

0 comments on commit feec83e

Please sign in to comment.