UNPKG

@horizon-modules/arbo-crm-to-property-v2

Version:

Conversor de dados do Arbo CRM para o formato Property Model V2

688 lines (682 loc) 19.8 kB
// src/discoverers/discoverType.ts function discoverType(arbo) { const tipoImovel = arbo.tipo_imovel?.toLowerCase() || ""; const categoria = arbo.categoria?.toLowerCase() || ""; const typeMap = { "casa": { type: "Casa", subtype: "Casa padr\xE3o" }, "casa t\xE9rrea": { type: "Casa", subtype: "Casa padr\xE3o" }, "sobrado": { type: "Casa", subtype: "Sobrado" }, "apartamento": { type: "Apartamento", subtype: "Apartamento" }, "cobertura": { type: "Apartamento", subtype: "Cobertura" }, "duplex": { type: "Apartamento", subtype: "Duplex" }, "triplex": { type: "Apartamento", subtype: "Triplex" }, "kitnet": { type: "Apartamento", subtype: "Kitnet" }, "studio": { type: "Apartamento", subtype: "Studio" }, "flat": { type: "Apartamento", subtype: "Flat" }, "loft": { type: "Apartamento", subtype: "Loft" }, "terreno": { type: "Terreno/Lote", subtype: "Terreno" }, "lote": { type: "Terreno/Lote", subtype: "Lote" }, "ch\xE1cara": { type: "Rural", subtype: "Ch\xE1cara" }, "s\xEDtio": { type: "Rural", subtype: "S\xEDtio" }, "fazenda": { type: "Rural", subtype: "Fazenda" }, "sala comercial": { type: "Comercial", subtype: "Sala comercial" }, "loja": { type: "Comercial", subtype: "Loja" }, "galp\xE3o": { type: "Barrac\xE3o/Armaz\xE9m", subtype: "Barrac\xE3o" }, "barrac\xE3o": { type: "Barrac\xE3o/Armaz\xE9m", subtype: "Barrac\xE3o" }, "armaz\xE9m": { type: "Barrac\xE3o/Armaz\xE9m", subtype: "Armaz\xE9m" }, "pr\xE9dio": { type: "Comercial", subtype: "Pr\xE9dio comercial" }, "ponto comercial": { type: "Comercial", subtype: "Ponto comercial" } }; for (const [key, value] of Object.entries(typeMap)) { if (tipoImovel.includes(key) || categoria.includes(key)) { return value; } } if (categoria.includes("comercial")) { return { type: "Comercial", subtype: "Im\xF3vel comercial" }; } if (categoria.includes("residencial")) { return { type: "Casa", subtype: "Casa padr\xE3o" }; } return { type: "Outros", subtype: "Outros" }; } // src/discoverers/discoverOperation.ts function discoverOperation(arbo) { const finalidade = arbo.finalidade?.toLowerCase() || ""; if (finalidade.includes("venda") || finalidade.includes("vender")) { return "sale"; } if (finalidade.includes("aluguel") || finalidade.includes("alugar") || finalidade.includes("loca\xE7\xE3o")) { return "rent"; } if (finalidade.includes("temporada")) { return "season"; } if (arbo.valor_venda && arbo.valor_venda > 0) { return "sale"; } if (arbo.valor_aluguel && arbo.valor_aluguel > 0) { return "rent"; } return "sale"; } // src/discoverers/discoverAttributes.ts function discoverAttributes(arbo, operation, type, subtype, options = {}) { const attributes = []; if (arbo.qtd_quartos && arbo.qtd_quartos > 0) { attributes.push({ key: "bedrooms", ref: "bedroom", type: "amount", label: "Quarto(s)", value: arbo.qtd_quartos, section: "rooms" }); } if (arbo.qtd_banheiro && arbo.qtd_banheiro > 0) { attributes.push({ key: "bathrooms", ref: "bathroom", type: "amount", label: "Banheiro(s)", value: arbo.qtd_banheiro, section: "rooms" }); } if (arbo.qtd_suites && arbo.qtd_suites > 0) { attributes.push({ key: "suites", ref: "suites", tags: ["has-suite"], type: "amount", label: "Su\xEDte(s)", value: arbo.qtd_suites, section: "rooms" }); } if (arbo.area_total && arbo.area_total > 0) { attributes.push({ key: "total-area", ref: "total-area", type: "area", label: "\xC1rea total - m\xB2", value: arbo.area_total.toString(), section: "feature" }); } if (arbo.area_privativa && arbo.area_privativa > 0) { attributes.push({ key: "util-area", type: "number", label: "\xC1rea \xFAtil - m\xB2", value: arbo.area_privativa.toString(), section: "feature" }); } if (arbo.qtd_vagas && arbo.qtd_vagas > 0) { attributes.push({ key: "garage", ref: "garage", type: "amount", label: "Vaga(s) na garagem", value: arbo.qtd_vagas, section: "feature" }); } if (arbo.caracteristicas && arbo.caracteristicas.length > 0) { const charMap = { "cozinha": { key: "kitchen", type: "bool", label: "Cozinha", value: true, section: "rooms" }, "sala de estar": { key: "living-room", type: "bool", label: "Sala de estar", value: true, section: "rooms" }, "sala de jantar": { key: "dinner-room", type: "bool", label: "Sala de jantar", value: true, section: "rooms" }, "\xE1rea de servi\xE7o": { key: "service-area", type: "bool", label: "\xC1rea de servi\xE7o", value: true, section: "rooms" }, "lavanderia": { key: "service-area", type: "bool", label: "\xC1rea de servi\xE7o", value: true, section: "rooms" }, "closet": { key: "closet ", type: "bool", label: "Closet ", value: true, section: "rooms" }, "sala de tv": { key: "tv-room", type: "bool", label: "Sala de TV", value: true, section: "rooms" }, "escrit\xF3rio": { key: "office", type: "bool", label: "Escrit\xF3rio", value: true, section: "rooms" }, "espa\xE7o gourmet": { key: "gourmet-space", type: "bool", label: "Espa\xE7o Gourmet", value: true, section: "rooms" }, "\xE1rea gourmet": { key: "gourmet-space", type: "bool", label: "Espa\xE7o Gourmet", value: true, section: "rooms" }, "varanda": { key: "balcony", tags: ["balcony"], type: "text", label: "Sacada", value: "padrao", section: "rooms", "value.label": "Padr\xE3o" }, "sacada": { key: "balcony", tags: ["balcony"], type: "text", label: "Sacada", value: "padrao", section: "rooms", "value.label": "Padr\xE3o" }, "su\xEDte master": { key: "master-suite", tags: ["suite"], type: "bool", label: "Su\xEDte Master", value: true, section: "rooms" }, "piscina": { key: "pool", type: "bool", label: "Piscina", value: true, section: "improvement" }, "churrasqueira": { key: "barbecue", tags: ["bbq"], type: "bool", label: "Churrasqueira", value: true, section: "improvement" }, "\xE1rea de lazer": { key: "recreation-area", type: "bool", label: "\xC1rea de lazer", value: true, section: "improvement" }, "playground": { key: "playground", type: "bool", label: "Parquinho", value: true, section: "improvement" }, "seguran\xE7a 24h": { key: "security-guard", tags: ["security"], type: "bool", label: "Seguran\xE7a 24h", value: true, section: "improvement" }, "portaria 24h": { key: "security-guard", tags: ["security"], type: "bool", label: "Seguran\xE7a 24h", value: true, section: "improvement" } }; const addedKeys = /* @__PURE__ */ new Set(); for (const char of arbo.caracteristicas) { const charLower = char.toLowerCase(); for (const [key, attr] of Object.entries(charMap)) { if (charLower.includes(key) && !addedKeys.has(attr.key)) { attributes.push(attr); addedKeys.add(attr.key); } } } } if (arbo.end_condominio || arbo.valor_condominio && arbo.valor_condominio > 0) { attributes.push({ key: "in-condominium", tags: ["in-condominium"], type: "bool", label: "Em condom\xEDnio", value: true, section: "improvement" }); attributes.push({ key: "em-condominio", value: true }); } if (options.agentId) { attributes.push({ key: "agent", value: options.agentId }); } if (arbo.latitude && arbo.longitude) { attributes.push({ key: "position", value: `${arbo.latitude},${arbo.longitude}` }); } const city = arbo.end_cidade && arbo.end_estado ? `${arbo.end_cidade} - ${arbo.end_estado}` : arbo.end_cidade || ""; if (city) { attributes.push({ key: "city", value: city }); } attributes.push( { key: "description", value: arbo.descricao || "" }, { key: "type", value: type }, { key: "title", value: arbo.titulo || "" }, { key: "objective", value: "Residencial" }, { key: "reference", value: arbo.codigo || "" } ); if (options.clientId) { attributes.push({ key: "client", value: options.clientId }); } attributes.push( { key: "model", value: `${subtype.toLowerCase().replace(/ /g, "-")}@1.0` }, { key: "id", value: `ppt_${generateId()}` }, { key: "modified_at", value: (/* @__PURE__ */ new Date()).toISOString() } ); if (arbo.end_logradouro) { attributes.push({ key: "address-street", value: arbo.end_logradouro }); } if (operation === "sale" && arbo.valor_venda) { attributes.push( { key: "value", value: arbo.valor_venda }, { key: "sale-value", ref: "sale-value", type: "currency", value: arbo.valor_venda } ); } else if (operation === "rent" && arbo.valor_aluguel) { attributes.push( { key: "value", value: arbo.valor_aluguel }, { key: "rent-value", ref: "rent-value", type: "currency", value: arbo.valor_aluguel } ); } attributes.push( { key: "published", value: false }, { key: "postal-code", value: arbo.end_cep || "" }, { key: "friendly-url", value: arbo.codigo?.toLowerCase() || "" } ); if (arbo.end_complemento) { attributes.push({ key: "address-complement", value: arbo.end_complemento }); } if (arbo.end_bairro) { attributes.push({ key: "district", value: arbo.end_bairro }); } attributes.push( { key: "operation", value: operation }, { key: "integrations", value: [ { key: "imovelweb", title: "Im\xF3vel Web" }, { key: "chavesnamao", title: "Chaves na m\xE3o" }, { key: "procure-imovel", title: "Procure Im\xF3vel" }, { key: "vivareal", title: "Viva Real" }, { key: "zapimoveis", title: "Zap Im\xF3veis" }, { key: "olx", title: "OLX" } ] } ); const fullAddress = buildFullAddress(arbo); if (fullAddress) { attributes.push({ key: "full-address", ref: "address", type: "address", value: fullAddress, section: "location" }); } attributes.push({ key: "subtype", value: subtype }); return attributes; } function buildFullAddress(arbo) { const parts = []; if (arbo.end_logradouro) { parts.push(arbo.end_logradouro); if (arbo.end_numero) { parts[parts.length - 1] += `, ${arbo.end_numero}`; } } if (arbo.end_complemento) { parts.push(arbo.end_complemento); } if (arbo.end_bairro) { parts.push(arbo.end_bairro); } const cityState = []; if (arbo.end_cidade) cityState.push(arbo.end_cidade); if (arbo.end_estado) cityState.push(arbo.end_estado); if (cityState.length > 0) { parts.push(cityState.join(" - ")); } return parts.join(" - "); } function generateId() { const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; let result = ""; for (let i = 0; i < 28; i++) { result += chars.charAt(Math.floor(Math.random() * chars.length)); } return result; } // src/discoverers/discoverMedia.ts function discoverMedia(arbo) { const media = { videos: [], tour360: [], pictures: [] }; if (arbo.fotos && arbo.fotos.length > 0) { const sortedPhotos = [...arbo.fotos].sort((a, b) => { if (a.principal && !b.principal) return -1; if (!a.principal && b.principal) return 1; return (a.ordem || 999) - (b.ordem || 999); }); media.pictures = sortedPhotos.map((foto, index) => ({ id: generatePhotoId(), src: foto.url, name: extractFileName(foto.url) || `foto_${index + 1}.jpg`, label: extractFileName(foto.url) || `foto_${index + 1}.jpg` })); } if (arbo.url_video) { media.videos.push({ url: arbo.url_video, type: "youtube" }); } if (arbo.url_tour) { media.tour360.push({ url: arbo.url_tour, type: "external" }); } return media; } function generatePhotoId() { return Math.random().toString().slice(2, 20); } function extractFileName(url) { try { const urlParts = url.split("/"); const fileName = urlParts[urlParts.length - 1]; return fileName.split("?")[0]; } catch { return ""; } } function discoverThumbnails(arbo, media) { if (media.pictures.length > 0) { return media.pictures[0].src; } if (arbo.fotos && arbo.fotos.length > 0) { const mainPhoto = arbo.fotos.find((f) => f.principal); if (mainPhoto) return mainPhoto.url; return arbo.fotos[0].url; } return ""; } // src/discoverers/discoverTags.ts function discoverTags(arbo, attributes, operation) { const tags = /* @__PURE__ */ new Set(); tags.add(operation); for (const attr of attributes) { if (attr.tags) { attr.tags.forEach((tag) => tags.add(tag)); } } if (arbo.caracteristicas) { const tagMap = { "piscina": "pool", "churrasqueira": "bbq", "seguran\xE7a": "security", "portaria": "security", "\xE1rea de lazer": "recreation", "playground": "playground", "academia": "gym", "sal\xE3o de festas": "party-room", "quadra": "court", "jardim": "garden", "pet place": "pet-friendly", "pet": "pet-friendly", "mobiliado": "furnished", "semi mobiliado": "semi-furnished" }; for (const char of arbo.caracteristicas) { const charLower = char.toLowerCase(); for (const [key, tag] of Object.entries(tagMap)) { if (charLower.includes(key)) { tags.add(tag); } } } } const tipo = arbo.tipo_imovel?.toLowerCase() || ""; if (tipo.includes("cobertura")) tags.add("penthouse"); if (tipo.includes("duplex")) tags.add("duplex"); if (tipo.includes("triplex")) tags.add("triplex"); if (tipo.includes("loft")) tags.add("loft"); const categoria = arbo.categoria?.toLowerCase() || ""; if (categoria.includes("residencial")) tags.add("residencial"); if (categoria.includes("comercial")) tags.add("comercial"); if (arbo.mobiliado) tags.add("furnished"); if (arbo.permuta) tags.add("exchange"); if (arbo.financiamento) tags.add("financing"); return Array.from(tags).join(" "); } function discoverKeywords(arbo, attributes) { const keywords = /* @__PURE__ */ new Set(); if (arbo.codigo) keywords.add(arbo.codigo.toLowerCase()); if (arbo.tipo_imovel) keywords.add(arbo.tipo_imovel.toLowerCase()); if (arbo.categoria) keywords.add(arbo.categoria.toLowerCase()); const titleWords = (arbo.titulo || "").toLowerCase().split(/\s+/); const descWords = (arbo.descricao || "").toLowerCase().split(/\s+/); const allWords = [...titleWords, ...descWords]; allWords.forEach((word) => { const cleanWord = word.replace(/[^\w]/g, ""); if (cleanWord.length > 2) { keywords.add(cleanWord); } }); if (arbo.end_cidade) keywords.add(arbo.end_cidade.toLowerCase()); if (arbo.end_bairro) keywords.add(arbo.end_bairro.toLowerCase()); if (arbo.end_estado) keywords.add(arbo.end_estado.toLowerCase()); if (arbo.caracteristicas) { arbo.caracteristicas.forEach((char) => { const words = char.toLowerCase().split(/\s+/); words.forEach((word) => { const cleanWord = word.replace(/[^\w]/g, ""); if (cleanWord.length > 2) { keywords.add(cleanWord); } }); }); } attributes.forEach((attr) => { if (attr.key) keywords.add(attr.key.replace(/[^a-z0-9]/gi, "-")); if (typeof attr.value === "string" && attr.value.length > 2) { keywords.add(attr.value.toLowerCase().replace(/[^\w]/g, "")); } }); return Array.from(keywords).join(" "); } // src/discoverers/discoverSearch.ts function discoverPropertySearch(arbo, id, title, reference, type, subtype, operation, price, tags, keywords, description, attributes) { const city = arbo.end_cidade && arbo.end_estado ? `${arbo.end_cidade} - ${arbo.end_estado}` : arbo.end_cidade || ""; const bedrooms = arbo.qtd_quartos || 0; const bathrooms = arbo.qtd_banheiro || 0; const garage = arbo.qtd_vagas || 0; const area = arbo.area_total || arbo.area_privativa || 0; const cleanDescription = description.toLowerCase().replace(/[^\w\s]/g, " ").replace(/\s+/g, " ").trim(); return { id, title, reference, type, subtype, operation, price, tags, keywords, description: cleanDescription, highlighted_date: null, state: arbo.end_estado || null, city, district: arbo.end_bairro || "", lat: arbo.latitude || 0, lon: arbo.longitude || 0, created_at: (/* @__PURE__ */ new Date()).toISOString(), modified_at: null, updated_at: null, bed: bedrooms, bath: bathrooms, garage, area }; } // src/converter.ts function convertArboToPropertyV2(arbo, options = {}) { const { type, subtype } = discoverType(arbo); const operation = discoverOperation(arbo); const attributes = discoverAttributes(arbo, operation, type, subtype, options); const media = discoverMedia(arbo); const thumbnails = discoverThumbnails(arbo, media); const tags = options.generateTags !== false ? discoverTags(arbo, attributes, operation) : ""; const keywords = options.generateKeywords !== false ? discoverKeywords(arbo, attributes) : ""; const title = arbo.titulo || ""; const description = arbo.descricao || ""; const reference = arbo.codigo || ""; const price = operation === "sale" ? arbo.valor_venda || 0 : arbo.valor_aluguel || 0; const id = arbo.ref_id; const now = (/* @__PURE__ */ new Date()).toISOString(); const propertySearch = discoverPropertySearch( arbo, id, title, reference, type, subtype, operation, price, tags, keywords, description, attributes ); const propertyV2 = { id, source_id: arbo.ref_id, reference, title, description, type, subtype, operation, attributes, media, tags, keywords, thumbnails: options.defaultThumbnail || thumbnails, web_code: null, provider: "arbo-crm", index: null, seo: null, visibility: null, preview: null, created_at: arbo.created_at || now, modified_at: arbo.updated_at || now, updated_at: now, property_search: [propertySearch] }; return propertyV2; } function convertMultipleArboToPropertyV2(arboProperties, options = {}) { return arboProperties.map((arbo) => convertArboToPropertyV2(arbo, options)); } export { convertArboToPropertyV2, convertMultipleArboToPropertyV2, discoverAttributes, discoverKeywords, discoverMedia, discoverOperation, discoverPropertySearch, discoverTags, discoverThumbnails, discoverType }; //# sourceMappingURL=index.mjs.map