UNPKG

@horizon-labs/property-model-v3

Version:

Modelo de propriedades imobiliárias v3 - Sistema de atributos dinâmicos

423 lines (418 loc) 21.4 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { PropertyAttributesModel: () => PropertyAttributesModel, formatListModel: () => formatListModel, mergePropertyAttributesModel: () => mergePropertyAttributesModel, preparaAttrValueLabel: () => preparaAttrValueLabel, propertyV3CustomMapper: () => propertyV3CustomMapper, sortAttributes: () => sortAttributes, unitListModel: () => unitListModel, verifyAttrKeyInPropertyV3Model: () => verifyAttrKeyInPropertyV3Model }); module.exports = __toCommonJS(index_exports); // src/models/property-attributes-model.ts var PropertyAttributesModel = [ // Comercial { key: "operacao", label: "Opera\xE7\xE3o", type: "String[]", cat: "comercial", order: 1 }, { key: "etapa_lancamento", label: "Etapa do lan\xE7amento", type: "String[]", cat: "comercial", order: 2 }, { key: "status_comercial", label: "Status comercial", type: "String[]", cat: "comercial", order: 3 }, { key: "destaque", label: "Im\xF3vel em destaque", type: "Boolean", cat: "comercial", order: 4 }, { key: "exclusividade", label: "Exclusividade do im\xF3vel", type: "Boolean", cat: "comercial", order: 5 }, { key: "financiavel", label: "Financi\xE1vel", type: "Boolean", cat: "comercial", order: 6 }, { key: "seguro_fianca", label: "Seguro fian\xE7a", type: "Boolean", cat: "comercial", order: 7 }, { key: "aceita_permuta", label: "Aceita permuta", type: "Boolean", cat: "comercial", order: 8 }, { key: "aceita_parcelamento", label: "Aceita parcelamento", type: "Boolean", cat: "comercial", order: 9 }, // Valores { key: "valor_condominio", label: "Valor do condom\xEDnio", type: "Number", role: "currency", unit: "BRL", cat: "valores", order: 20 }, { key: "valor_total_venda", label: "Valor total de venda", type: "Number", role: "currency", unit: "BRL", cat: "valores", composedLabel: "{{valueLabel}}", order: 21 }, { key: "valor_total_mensal", label: "Valor total de loca\xE7\xE3o", type: "Number", role: "currency", unit: "BRL", cat: "valores", composedLabel: "{{valueLabel}} /m\xEAs", order: 22 }, { key: "valor_venda", label: "Valor de venda", type: "Number", role: "currency", unit: "BRL", cat: "valores", composedLabel: "{{valueLabel}}", order: 23 }, { key: "valor_locacao", label: "Valor de loca\xE7\xE3o mensal", type: "Number", role: "currency", unit: "BRL", cat: "valores", composedLabel: "{{valueLabel}} /m\xEAs", order: 24 }, { key: "valor_diaria", label: "Valor da di\xE1ria", type: "Number", role: "currency", unit: "BRL", cat: "valores", composedLabel: "{{valueLabel}} /dia", order: 25 }, { key: "valor_pacote_dias", label: "Valor do pacote de dias", type: "Number", role: "currency", unit: "BRL", cat: "valores", order: 26 }, { key: "valor_iptu", label: "Valor do IPTU", type: "Number", role: "currency", unit: "BRL", cat: "valores", order: 27 }, { key: "valor_fci", label: "Valor do Fundo de conserva\xE7\xE3o", type: "Number", role: "currency", unit: "BRL", cat: "valores", order: 28 }, { key: "valor_seguro_incendio", label: "Valor do seguro inc\xEAndio", type: "Number", role: "currency", unit: "BRL", cat: "valores", order: 29 }, { key: "valor_m2", label: "Valor do m\xB2", type: "Number", role: "currency", unit: "BRL", cat: "valores", order: 30 }, { key: "valor_taxa_limpeza", label: "Valor da taxa de limpeza", type: "Number", role: "currency", unit: "BRL", cat: "valores", order: 31 }, { key: "valor_taxa_esgoto", label: "Valor da taxa de esgoto", type: "Number", role: "currency", unit: "BRL", cat: "valores", order: 32 }, { key: "moeda", label: "Unidade monet\xE1ria", type: "String", cat: "valores", order: 33 }, // Situações { key: "alugado", label: "Alugado", type: "Boolean", cat: "situacoes", order: 40 }, { key: "vendido", label: "Vendido", type: "Boolean", cat: "situacoes", order: 41 }, { key: "reservado", label: "Reservado", type: "Boolean", cat: "situacoes", order: 42 }, { key: "situacao_ocupacao", label: "Situa\xE7\xE3o de ocupa\xE7\xE3o", type: "String", cat: "situacoes", order: 43 }, { key: "financiado", label: "Financiado", type: "Boolean", cat: "situacoes", order: 44 }, // Legal / Documental { key: "averbado", label: "Averbado", type: "Boolean", cat: "legal", order: 60 }, { key: "escriturado", label: "Escriturado", type: "Boolean", cat: "legal", order: 61 }, { key: "incorporado", label: "Incorporado", type: "Boolean", cat: "legal", order: 62 }, // Normas / Permissões / Exigências { key: "numero_pessoas", label: "N\xFAmero de pessoas", type: "Number", role: "count", cat: "normas", order: 81 }, { key: "aceita_pet", label: "Aceita Pet", type: "Boolean", cat: "normas", order: 82 }, // Localização { key: "endereco_pais", label: "Pa\xEDs", type: "String", cat: "localizacao", order: 101 }, { key: "endereco_cep", label: "CEP", type: "String", cat: "localizacao", order: 102 }, { key: "endereco_estado", label: "Estado", type: "String", cat: "localizacao", order: 103 }, { key: "endereco_cidade", label: "Cidade", type: "String", cat: "localizacao", order: 104 }, { key: "endereco_bairro", label: "Bairro", type: "String", cat: "localizacao", order: 105 }, { key: "endereco_logradouro", label: "Logradouro", type: "String", cat: "localizacao", order: 106 }, { key: "endereco_numero", label: "N\xFAmero do im\xF3vel", type: "String", cat: "localizacao", order: 107 }, { key: "endereco_complemento", label: "Complemento", type: "String", cat: "localizacao", order: 108 }, { key: "endereco_referencia", label: "Refer\xEAncia (endere\xE7o)", type: "String", cat: "localizacao", order: 109 }, { key: "latitude", label: "Latitude", type: "Number", cat: "localizacao", order: 110 }, { key: "longitude", label: "Longitude", type: "Number", cat: "localizacao", order: 111 }, { key: "geoposicionamento", label: "Geoposicionamento", type: "String", cat: "localizacao", order: 112 }, { key: "endereco_completo", label: "Endere\xE7o completo", type: "String", cat: "localizacao", order: 113 }, { key: "endereco_bairro_cidade_uf", label: "Bairro + Cidade + UF", type: "String", cat: "localizacao", order: 114 }, // Condomínio { key: "condominio_nome", label: "Nome do condom\xEDnio", type: "String", cat: "condominio", order: 120 }, { key: "condominio_tipo", label: "Tipo do condom\xEDnio", type: "String", cat: "condominio", order: 121 }, { key: "condominio_fechado", label: "Condom\xEDnio fechado", type: "Boolean", cat: "condominio", order: 122 }, // Localidade { key: "distancia_mar", label: "Dist\xE2ncia do mar", type: "Number", role: "distance", unit: "m", cat: "localidade", order: 141 }, { key: "imovel_no_litoral", label: "Im\xF3vel no litoral", type: "Boolean", cat: "localidade", order: 142 }, { key: "frente_mar", label: "Frente para o mar", type: "Boolean", cat: "localidade", order: 144 }, { key: "vista_mar", label: "Vista para o mar", type: "Boolean", cat: "localidade", order: 146 }, // Estrutura do imóvel { key: "tipo", label: "Tipo", type: "String", cat: "estrutura", order: 160 }, { key: "subtipo", label: "Subtipo", type: "String", cat: "estrutura", order: 161 }, { key: "area_privativa", label: "\xC1rea privativa", type: "Number", role: "area", unit: "m\xB2", cat: "estrutura", composedLabel: "{{valueLabel}} priv.", iconName: "area", order: 163 }, { key: "area_total", label: "\xC1rea Total", type: "Number", role: "area", unit: "m\xB2", cat: "estrutura", composedLabel: "{{valueLabel}} total", iconName: "area", order: 164 }, { key: "area_terreno", label: "\xC1rea do terreno", type: "Number", role: "area", unit: "m\xB2", cat: "estrutura", composedLabel: "{{valueLabel}} terreno", iconName: "area", order: 165 }, { key: "padrao_imovel", label: "Padr\xE3o do im\xF3vel", type: "String", cat: "estrutura", order: 166 }, { key: "fase_obra", label: "Fase da obra", type: "String", cat: "estrutura", order: 167 }, { key: "em_condominio", label: "Em condom\xEDnio", type: "Boolean", cat: "estrutura", order: 168 }, { key: "finalidade", label: "Finalidade (prop\xF3sito)", type: "String", cat: "estrutura", order: 169 }, { key: "estado_conservacao", label: "Estado da conserva\xE7\xE3o do im\xF3vel", type: "String", cat: "estrutura", order: 170 }, { key: "estado_imovel", label: "Status da obra + uso do im\xF3vel", type: "String", cat: "estrutura", order: 171 }, { key: "posicao_solar", label: "Posi\xE7\xE3o solar", type: "String", cat: "estrutura", order: 172 }, { key: "posicao_no_terreno", label: "Posi\xE7\xE3o do im\xF3vel no terreno", type: "String", cat: "estrutura", order: 173 }, { key: "tipo_piso", label: "Tipo de piso", type: "String", cat: "estrutura", order: 174 }, { key: "tipos_piso", label: "Tipos de piso", type: "String[]", cat: "estrutura", order: 175 }, { key: "material_imovel", label: "Material do im\xF3vel", type: "String", cat: "estrutura", order: 176 }, { key: "materiais_imovel", label: "Materiais do im\xF3vel", type: "String[]", cat: "estrutura", order: 177 }, { key: "area_construida", label: "\xC1rea constru\xEDda", type: "Number", role: "area", unit: "m\xB2", cat: "estrutura", order: 178 }, { key: "area_util", label: "\xC1rea \xFAtil", type: "Number", role: "area", unit: "m\xB2", cat: "estrutura", order: 179 }, { key: "data_entrega_obra", label: "Data de entrega da obra", type: "String", role: "date", cat: "estrutura", order: 180 }, { key: "ano_construcao", label: "Ano da constru\xE7\xE3o", type: "String", role: "year", cat: "estrutura", order: 181 }, { key: "topografia_terreno", label: "Topografia do terreno", type: "String", cat: "estrutura", order: 182 }, { key: "pintura", label: "Pintura", type: "String", cat: "estrutura", order: 183 }, { key: "pinturas_revestimentos", label: "Pinturas e revestimentos", type: "String[]", cat: "estrutura", order: 184 }, { key: "tipo_esquadria", label: "Tipo de esquadrias", type: "String", cat: "estrutura", order: 185 }, { key: "tipos_esquadrias", label: "Tipos de esquadrias", type: "String[]", cat: "estrutura", order: 186 }, { key: "tipo_forro", label: "Tipo do forro", type: "String", cat: "estrutura", order: 187 }, { key: "tipos_forros", label: "Tipos de forros", type: "String[]", cat: "estrutura", order: 188 }, { key: "tipos_coberturas", label: "Tipos de coberturas", type: "String[]", cat: "estrutura", order: 189 }, { key: "terreno_comprimento", label: "Comprimento do terreno", type: "Number", role: "distance", unit: "m", cat: "estrutura", order: 190 }, { key: "terreno_largura", label: "Largura do Terreno", type: "Number", role: "distance", unit: "m", cat: "estrutura", order: 191 }, { key: "cores", label: "Cores do im\xF3vel", type: "String[]", cat: "estrutura", order: 192 }, { key: "andares", label: "N\xFAmero de andares", type: "Number", role: "count", cat: "estrutura", order: 193 }, { key: "medida_distancia", label: "Tipo de medida de dist\xE2ncia", type: "String", cat: "estrutura", order: 194 }, { key: "medida_area", label: "Tipo de medida de \xE1rea", type: "String", cat: "estrutura", order: 195 }, // Corretor { key: "corretor_id", label: "Corretor \u2192 ID", type: "String", cat: "corretor", order: 210 }, { key: "corretor_nome", label: "Corretor \u2192 Nome", type: "String", cat: "corretor", order: 211 }, // Dependências { key: "dormitorios", label: "Dormit\xF3rios", type: "Number", role: "count", cat: "dependencias", composedLabel: "{{valueLabel}} dormit\xF3rio{{p:s}}", iconName: "bedroom", order: 230 }, { key: "banheiros", label: "Banheiros", type: "Number", role: "count", cat: "dependencias", composedLabel: "{{valueLabel}} banheiro{{p:s}}", iconName: "bathroom", order: 231 }, { key: "suites", label: "Su\xEDtes", type: "Number", role: "count", cat: "dependencias", composedLabel: "Sendo {{valueLabel}} su\xEDte{{p:s}}", iconName: "suite", order: 232 }, { key: "vagas_garagem", label: "Vagas na garagem", type: "Number", role: "count", cat: "dependencias", composedLabel: "{{valueLabel}} vaga{{p:s}}", iconName: "garage", order: 233 }, // Características em geral { key: "mobiliado", label: "Mobiliado", type: "Boolean", cat: "caracteristicas", order: 250 } // { key: "caracteristicas", label: "Características (lista)", type: "String[]", cat: "caracteristicas" order: 1, }, ]; // src/models/property-attributes-fields-list-model.ts var unitListModel = { area: [ { key: "m\xB2", aliases: ["m2"], label: "m\xB2", labelDisplay: "Metros quadrados" }, { key: "ha", aliases: ["hectare", "hectares"], label: "ha", labelDisplay: "Hectares" }, { key: "km\xB2", aliases: ["km2"], label: "km\xB2", labelDisplay: "Quil\xF4metros quadrados" } ], length: [ { key: "m", aliases: ["metro", "meter", "meters"], label: "m", labelDisplay: "Metros" }, { key: "km", aliases: ["quilometro", "kilometer", "kilometers"], label: "km", labelDisplay: "Quil\xF4metros" } ], currency: [ { key: "BRL", aliases: [], label: "R$", labelDisplay: "Real Brasileiro", locale: "pt-BR" } ] }; var formatListModel = { // Em desenvolvimento futuro // color: [ // { // key: "rgb", // label: "RGB", // }, // { // key: "cmyk", // label: "CMYK", // }, // ], }; // src/utils/index.ts function verifyAttrKeyInPropertyV3Model(key) { return PropertyAttributesModel.find((attr) => attr.key == key); } function mergePropertyAttributesModel(base, overrides) { const map = new Map(base.map((attr) => [attr.key, { ...attr }])); for (const overrideAttr of overrides) { const baseAttr = map.get(overrideAttr.key); if (baseAttr) { for (const field in overrideAttr) { baseAttr[field] = overrideAttr[field]; } map.set(overrideAttr.key, baseAttr); } else { map.set(overrideAttr.key, { ...overrideAttr }); } } return Array.from(map.values()); } function sortAttributes(attributes, sortKeys = []) { return [...attributes].sort((a, b) => { for (const rule of sortKeys) { const [field, direction] = rule.split(":"); const valA = a[field]; const valB = b[field]; if (valA === void 0 || valB === void 0) continue; const isAsc = direction === "asc"; const isDesc = direction === "desc"; if (!isAsc && !isDesc) { console.warn(`Dire\xE7\xE3o inv\xE1lida: "${direction}". Use "asc" ou "desc".`); continue; } if (valA < valB) return isAsc ? -1 : 1; if (valA > valB) return isAsc ? 1 : -1; } return 0; }); } var preparaAttrValueLabel = function(valor) { return Array.isArray(valor) ? `${valor.slice(0, -1).join(", ")} e ${valor[valor.length - 1]}` : valor; }; // src/custom-mapper/index.ts var import_ramda = require("ramda"); function upsertAttribute(attributes, attr) { const index = attributes.findIndex((item) => item.key === attr.key); if (index !== -1) { attributes[index] = attr; } else { attributes.push(attr); } } function addTags(property, list) { const current = property.tags ? property.tags.split(" ") : []; property.tags = (0, import_ramda.union)(current, list).join(" "); } function removeTags(property, list) { const current = property.tags ? property.tags.split(" ") : []; property.tags = current.filter((tag) => !list.includes(tag)).join(" "); } function removeAttr(attributes, key) { const index = attributes.findIndex((item) => item.key === key); if (index !== -1) attributes.splice(index, 1); } var actionRunner = { upsertAttr: (property, action) => { const { key, fn, ...rest } = action; upsertAttribute(property.attributes, { key, ...rest }); }, removeAttr: (property, action) => { removeAttr(property.attributes, action.key); }, addTags: (property, action) => { addTags(property, action.list); }, removeTags: (property, action) => { removeTags(property, action.list); } }; function applyAttrRules(attr, rules, property) { const actions = rules?.[attr.value]; if (!actions) return property; actions.forEach((action) => { const fn = actionRunner[action.fn]; if (fn) { const resolvedAction = resolvePlaceholders(action, attr); fn(property, resolvedAction); } }); return property; } function applyTagRules(tags, rules, property) { const tagsArray = tags.split(" "); tagsArray.forEach((tag) => { const actions = rules?.[tag]; if (!actions) return; actions.forEach((action) => { const fn = actionRunner[action.fn]; if (fn) fn(property, action); }); }); } function applyReferenceRules(reference, rules, property) { const actions = rules?.[reference]; if (!actions) return; actions.forEach((action) => { const fn = actionRunner[action.fn]; if (fn) fn(property, action); }); } function matchCondition(attrValue, condition) { if (!condition) return true; const attrAsArray = Array.isArray(attrValue) ? attrValue : typeof attrValue === "string" ? [attrValue] : []; for (const operator in condition) { const expected = condition[operator]; switch (operator) { case "eq": if (attrValue !== expected) return false; break; case "not_eq": if (attrValue === expected) return false; break; case "has": { const attrAsArray2 = Array.isArray(attrValue) ? attrValue : [attrValue]; const expectedArray = Array.isArray(expected) ? expected : [expected]; if (!expectedArray.every((val) => attrAsArray2.includes(val))) return false; break; } case "has_any": { const attrAsArray2 = Array.isArray(attrValue) ? attrValue : [attrValue]; const expectedArray = Array.isArray(expected) ? expected : [expected]; if (!expectedArray.some((val) => attrAsArray2.includes(val))) return false; break; } case "not_has": if (Array.isArray(expected)) { if (expected.some((val) => attrAsArray.includes(val))) return false; } else { if (attrAsArray.includes(expected)) return false; } break; case "gt": if (!(attrValue > expected)) return false; break; case "gte": if (!(attrValue >= expected)) return false; break; case "lt": if (!(attrValue < expected)) return false; break; case "lte": if (!(attrValue <= expected)) return false; break; default: return false; } } return true; } function resolvePlaceholders(action, sourceAttr) { const resolved = { ...action }; if (resolved.value === "{{value}}") { resolved.value = sourceAttr.value; } else if (typeof resolved.value === "string" && resolved.value.includes("{{value}}")) { resolved.value = resolved.value.replace( "{{value}}", String(sourceAttr.value) ); } return resolved; } function applyAttributesRules(attributes, rules, property) { for (const rule of rules) { const attr = attributes.find((a) => a.key === rule.key); if (!attr) continue; if (matchCondition(attr.value, rule.condition)) { for (const action of rule.rules) { const fn = actionRunner[action.fn]; if (fn) { const resolvedAction = resolvePlaceholders(action, attr); fn(property, resolvedAction); } } } } } function propertyV3CustomMapper(property, mapRules) { const newProperty = (0, import_ramda.clone)(property); const { attributes, reference, tags } = newProperty; const { attrTipoRules, referenceRules, tagsRules, attributesRules } = mapRules; attrTipoRules && attributes.forEach((attr) => { if (attr.key === "tipo") { applyAttrRules(attr, attrTipoRules, newProperty); } }); tagsRules && applyTagRules(tags, tagsRules, newProperty); referenceRules && applyReferenceRules(reference, referenceRules, newProperty); attributesRules && applyAttributesRules(attributes, attributesRules, newProperty); return newProperty; } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { PropertyAttributesModel, formatListModel, mergePropertyAttributesModel, preparaAttrValueLabel, propertyV3CustomMapper, sortAttributes, unitListModel, verifyAttrKeyInPropertyV3Model }); //# sourceMappingURL=index.js.map