Código
// Função auxiliar para formatar datas no padrão DD/MM/YYYY
function formatDate(dateString) {
if (!dateString) return null;
const date = new Date(dateString);
if (isNaN(date)) return null;
const day = String(date.getDate()).padStart(2, '0');
const month = String(date.getMonth() + 1).padStart(2, '0');
const year = date.getFullYear();
return `${day}/${month}/${year}`;
}
// Função auxiliar para calcular idade
function calculateAge(dateString) {
if (!dateString) return null;
const date = new Date(dateString);
if (isNaN(date)) return null;
const today = DateTime.now().startOf('day');
let age = today.year - date.getFullYear();
if (
today.month < date.getMonth() + 1 ||
(today.month === date.getMonth() + 1 && today.day < date.getDate())
) {
age--;
}
return age;
}
// Função auxiliar para extrair nomes
function extractNames(fullName) {
if (!fullName) return { firstName: '', lastName: '' };
const parts = fullName.trim().split(/\s+/);
const firstName = parts[0] || '';
const lastName = parts.length > 1 ? parts.slice(1).join(' ') : '';
return { firstName, lastName };
}
const user = $json;
const lead = user.lead;
const birthDate = user.birthDate;
const formattedDate = formatDate(birthDate);
const age = calculateAge(birthDate);
const { firstName, lastName } = extractNames(user.name);
function formatPhone(phone) {
return phone ? phone.replace('+55', '') : '';
}
const formattedUser = {
cpf: user.cpf,
uid: user.uid,
full_name: user.name,
phone: formatPhone(user.whatsappNumber),
email: user.email,
last_access: user.lastAccess,
notification_token: user.notificationToken,
is_valid_lead: user.isValidLead,
is_hard_bounced: user.isHardBounced,
has_active_follow_up: null,
ban_expiration_date: user.banExpirationDate,
has_recently_finished_follow_up: null,
exists: true,
address: user.address,
};
// Função para mapear registries sem mutar array externo
function mapRegistries(lead) {
if (!lead?.loansDetails || !Array.isArray(lead.loansDetails) || lead.loansDetails.length < 1) return null;
const registriesFound = new Set();
return lead.loansDetails.map((l) => {
const registry = l.Matricula;
if (!registry || registriesFound.has(registry.Numero)) {
return null;
}
registriesFound.add(registry.Numero);
return {
"covenant":
{
"acronym": $('SubWorkflow: ID Covenant').first().json.convenioAcronimo,
},
registry_number: registry.Numero,
occupancy: registry.Lotacao,
salary: l.Salario,
employee_type: {
description: registry.DescricaoVinculoServidor,
},
department: {
description: registry.Secretaria,
},
margins: {
total_loan_margin: l.MargemTotal,
available_loan_margin: l.MargemDisponivel,
total_clt_margin: null,
available_clt_margin: null,
reserved_loan_margin: null,
total_credit_card_margin: null,
available_credit_card_margin: null,
reserved_credit_card_margin: null,
available_compulsory_margin: l.LimiteDisponivelCartaoConsignado,
total_compulsory_margin: l.LimiteTotalCartaoConsignado,
reserved_compulsory_margin: null,
total_assistencial_benefit_margin: null,
available_assistencial_benefit_margin: null,
total_purchase_benefit_card_margin: null,
available_purchase_benefit_card_margin: null,
reserved_purchase_benefit_card_margin: null,
total_withdraw_benefit_card_margin: l.LimiteTotalCartaoBeneficios,
available_withdraw_benefit_card_margin: l.LimiteDisponivelCartaoBeneficios,
reserved_withdraw_benefit_card_margin: null,
},
inss: {
has_legal_representative: registry.PossuiRepresentanteLegal ?? null,
is_elegible_for_loan: registry.ElegivelEmprestimo ?? null,
is_released_for_loan: registry.LiberadoEmprestimo ?? null,
benefit_kind: {
code: registry.CodigoEspecieBeneficio ?? null,
description: null,
},
alimony: {
hasAlimony: registry.PossuiPensaoAlimenticia ?? null,
code: null,
description: null,
},
},
clt: {
admission_date: registry.DataAdmissao ?? null,
is_elegible_for_loan: null,
},
mode: "app",
created_at: null,
updated_at: null,
last_hygienization_date: null
};
}).filter(Boolean);
}
return {
user: formattedUser,
cpf: user.cpf,
opportunities: {},
proposals: {},
name: user.name,
first_name: firstName,
last_name: lastName,
birthdate: formattedDate,
age,
random_email: user.cpf ? `email_aleatorio_${user.cpf}@konsi.dev` : null,
phones: [
{
number: formatPhone(user.whatsappNumber),
importance: 1,
data_origin: 'app',
},
],
emails: [
{
email: user.email,
importance: 1,
data_origin: 'app',
},
],
registries: mapRegistries(lead),
};Saídas
- Objeto UnifiedLead completo com estrutura padronizada contendo:
user: Dados formatados do usuáriocpf,name,first_name,last_name: Identificaçãobirthdate,age: Dados demográficosphones,emails: Arrays de contatosregistries: Array de matrículas/vínculos formatadosopportunities,proposals: Objetos vazios (preenchidos depois)
Descrição adicional
Transforma dados do usuário do formato do app para o formato UnifiedLead padronizado. Realiza:
- Formatação de datas (DD/MM/YYYY)
- Cálculo de idade
- Extração de primeiro/último nome
- Formatação de telefone (remove +55)
- Mapeamento de registries com todas as margens e dados de vínculo
- Criação de email aleatório para testes
Relações
← Recebe de: 19-flow-variable---set-user-app-data → Envia para: 21-flow-variable---set-unified-lead
Observações
- Usa DateTime do Luxon para cálculo de idade
- Remove duplicatas de registries usando Set
- Preenche estrutura completa de margens mesmo quando alguns valores são null