Repository navigation
Regras de Negocio
Regras obrigatórias de cadastro (PJ sem usuário próprio; contatos só na PJ; usuário na PF; fluxo salesman / sellers-client) e diagrama de fluxo:
→ Cadastro-de-Pessoas-Contatos-Usuarios-e-Vendedores
Espelho API: https://github.com/ControleOnline/api-platform-people/wiki/Cadastro-de-Pessoas-Contatos-Usuarios-e-Vendedores
| Código | Nome | Descrição |
|---|---|---|
F |
Pessoa Física | CPF, nome, data de nascimento |
J |
Pessoa Jurídica | CNPJ, razão social, data de fundação |
A distinção é feita via campo peopleType. O módulo trata imagens, labels e comportamentos de forma diferente para cada tipo.
Um People pode ser vinculado a uma empresa através de um link com um linkType. Os tipos suportados são:
| linkType | Categoria | Descrição |
|---|---|---|
client |
Comercial | Cliente da empresa |
prospect |
CRM | Potencial cliente (em negociação) |
provider |
Compras | Fornecedor/prestador |
franchisee |
Franquia | Franqueado |
employee |
RH | Funcionário |
owner |
Societário | Sócio/proprietário |
director |
Societário | Diretor |
manager |
Societário | Gerente |
salesman |
Comercial | Vendedor |
after-sales |
Pós-venda | Responsável por pós-venda |
courier |
Logística | Entregador |
Os tipos employee, owner, director, manager, salesman, after-sales, courier são classificados como vínculos humanos. Eles são usados na página MyCompaniesPage para encontrar as empresas às quais o usuário pertence como pessoa (e não como cliente ou fornecedor).
A empresa ativa no contexto da sessão é:
- Lida do store
people.getters.currentCompany - Persistida via
currentCompanySelection.jsnolocalStorage(chavesession) - Usada como escopo padrão nos filtros de busca de pessoas
buildPeopleContextConfig(context) é o único ponto autorizado para normalizar context props:
- Recebe props brutas do componente pai
- Deduplica tipos, normaliza para minúsculo
- Define
defaultTypecomo o primeiro tipo disponível se não especificado - Calcula
hasTypeFilter(true quando há mais de 1 tipo disponível) - Não espalhar essa lógica em outros módulos
A lógica de imagem está encapsulada em peopleImage.js:
-
Pessoa física (
F): procura mídias dos tiposavatar,photo,profile,profile-photo; fallback para camposavatar,photo,image,profilePicture,picture,icon -
Pessoa jurídica (
J): procura mídias dos tiposicon,logo; fallback para camposicon,logo,image,avatar,photo,picture - Normaliza coleções aceitas:
people.media,people.medias,people.peopleMedia,people.peopleMedias
resolveLoggedUserId(currentUser) tenta extrair o ID numérico via múltiplos caminhos (fallback chain):
currentUser.user_idcurrentUser.userIdcurrentUser.user.idcurrentUser.user['@id']currentUser.idUser-
session.user_id(localStorage) session.userIdsession.user.idsession.user['@id']session['@id']
Isso garante compatibilidade com diferentes formatos de resposta de autenticação.
Dois helpers constroem os parâmetros de requisição à API:
Usado quando a busca é de pessoas vinculadas a uma empresa específica:
link.company = /people/{currentCompany.id}
link.linkType = selectedLinkType
Usado quando o objetivo é encontrar empresas às quais o usuário pertence:
company.people = /people/{user.id}
company.linkType = [tipos humanos resolvidos]
Ao trocar a foto de perfil, persistSessionAvatar(avatarFile):
- Lê a sessão atual do
localStorage - Substitui apenas o campo
avatar(preserva demais campos) - Salva de volta no
localStorage
O avatar null limpa a foto na sessão (remoção explícita).
O sub-store documentsTypes carrega dinamicamente os tipos disponíveis na API. O sub-store documents possui documentsTypes.js para mapear tipos conhecidos (CPF, CNPJ, RG, etc.).
- Cada pessoa/empresa pode ter domínios de acesso associados (URLs, apps, etc.)
- O store
people_domainspossui colunas configuradas viapeopleDomainColumns - Ações customizadas em
actions.jspara testes de domínio (testDomain) e status de carregamento (detailLoading) - Flag
isSavingseparada deisLoadingpara UI de feedback granular
Se initialShowAddModal === true e o modal ainda não foi aberto nessa montagem, People abre automaticamente o AddCompanyModal na primeira renderização. O controle é feito via useRef para evitar aberturas repetidas em re-renders.
Campos nominais digitados pelo usuário (nome, alias/fantasia) preservam a capitalização informada.
-
normalizeIdentityValue(helpers de My Companies / formulários) apenas faz trim e colapso de espaços — não aplicatoUpperCase/formatDisplayUppercase. - Cards de lista (People / My Companies) exibem o valor gravado sem forçar CAIXA ALTA.
- Utilitários
uppercaseText/formatDisplayUppercaseemui-commonficam reservados a códigos legítimos (ex.: UF), não a identidade de pessoa.
Página canônica (UI + API):
https://github.com/ControleOnline/ui-customers/wiki/Client-Details-People-Name-Case
Backend: People::getName() / getAlias() em api-platform-people devolvem o valor armazenado sem upper na leitura
https://github.com/ControleOnline/api-platform-people/wiki/People-Name-Alias-Case
Trilhas: app-community#626, #376.
A rota MANAGER /employees-index reutiliza People com contexto employee + owner + courier.
- O valor do filtro de coluna
link.linkTypepode chegar como string,{ value }ou array; a normalização para escalar é obrigatória antes desetSelectedLinkType(ver People-List-LinkType-Filters-Employees-Index). - Escopo de company: sempre
link.company= IRI dacurrentCompany. - Navegação de detalhe em contexto empresa usa
companyId(nãoclientId).
Detalhes e diagrama: People-List-LinkType-Filters-Employees-Index.