164 lines
6.3 KiB
JavaScript
164 lines
6.3 KiB
JavaScript
'use strict'
|
|
|
|
const { execute, queryOne, query } = require('../database/postgres')
|
|
|
|
class Cliente {
|
|
static findById(id) {
|
|
return queryOne('SELECT * FROM clientes WHERE id = $1', [id])
|
|
}
|
|
|
|
static findByCpfCnpj(cpfCnpj, tenantId) {
|
|
return queryOne('SELECT * FROM clientes WHERE cpf_cnpj = $1 AND tenant_id = $2', [cpfCnpj, tenantId])
|
|
}
|
|
|
|
static findByUserId(userId, tenantId) {
|
|
return queryOne('SELECT * FROM clientes WHERE user_id = $1 AND tenant_id = $2', [userId, tenantId])
|
|
}
|
|
|
|
static list(tenantId, { search, tipo, status, limit = 50, offset = 0 } = {}) {
|
|
const params = [tenantId]
|
|
let where = 'WHERE tenant_id = $1'
|
|
if (tipo) { params.push(tipo); where += ` AND tipo = $${params.length}` }
|
|
if (status) { params.push(status); where += ` AND status = $${params.length}` }
|
|
if (search) {
|
|
params.push(`%${search.replace(/[%_]/g, '\\$&')}%`)
|
|
where += ` AND (nome ILIKE $${params.length} OR cpf_cnpj ILIKE $${params.length} OR email ILIKE $${params.length})`
|
|
}
|
|
params.push(Math.min(Number(limit) || 50, 200))
|
|
params.push(Math.max(Number(offset) || 0, 0))
|
|
return query(
|
|
`SELECT * FROM clientes ${where} ORDER BY nome ASC LIMIT $${params.length - 1} OFFSET $${params.length}`,
|
|
params
|
|
)
|
|
}
|
|
|
|
static create({ tenant_id, tipo, nome, cpf_cnpj, email, status = 'ativo', user_id = null }) {
|
|
return execute(
|
|
`INSERT INTO clientes (tenant_id, tipo, nome, cpf_cnpj, email, status, user_id)
|
|
VALUES ($1,$2,$3,$4,$5,$6,$7) RETURNING *`,
|
|
[tenant_id, tipo, nome, cpf_cnpj, email || null, status, user_id]
|
|
)
|
|
}
|
|
|
|
static update(id, { nome, email, status }) {
|
|
return execute(
|
|
`UPDATE clientes SET nome=$1, email=$2, status=$3, updated_at=NOW() WHERE id=$4`,
|
|
[nome, email || null, status, id]
|
|
)
|
|
}
|
|
|
|
static delete(id) {
|
|
return execute('DELETE FROM clientes WHERE id = $1', [id])
|
|
}
|
|
|
|
// ── Endereços ─────────────────────────────────────────────
|
|
|
|
static listEnderecos(clienteId) {
|
|
return query('SELECT * FROM cliente_enderecos WHERE cliente_id = $1 ORDER BY principal DESC, id ASC', [clienteId])
|
|
}
|
|
|
|
static createEndereco({ cliente_id, tipo, cep, rua, numero, complemento, bairro, cidade, estado, referencia, principal }) {
|
|
return execute(
|
|
`INSERT INTO cliente_enderecos (cliente_id,tipo,cep,rua,numero,complemento,bairro,cidade,estado,referencia,principal)
|
|
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11) RETURNING *`,
|
|
[cliente_id, tipo || 'entrega', cep || null, rua || null, numero || null,
|
|
complemento || null, bairro || null, cidade || null, estado || null,
|
|
referencia || null, principal || false]
|
|
)
|
|
}
|
|
|
|
static updateEndereco(id, { tipo, cep, rua, numero, complemento, bairro, cidade, estado, referencia, principal }) {
|
|
return execute(
|
|
`UPDATE cliente_enderecos SET tipo=$1,cep=$2,rua=$3,numero=$4,complemento=$5,
|
|
bairro=$6,cidade=$7,estado=$8,referencia=$9,principal=$10 WHERE id=$11`,
|
|
[tipo, cep || null, rua || null, numero || null, complemento || null,
|
|
bairro || null, cidade || null, estado || null, referencia || null,
|
|
principal || false, id]
|
|
)
|
|
}
|
|
|
|
static setEndereçoPrincipal(clienteId, enderecoId) {
|
|
return execute(
|
|
`UPDATE cliente_enderecos SET principal = (id = $2) WHERE cliente_id = $1`,
|
|
[clienteId, enderecoId]
|
|
)
|
|
}
|
|
|
|
static deleteEndereco(id) {
|
|
return execute('DELETE FROM cliente_enderecos WHERE id = $1', [id])
|
|
}
|
|
|
|
// ── Telefones ─────────────────────────────────────────────
|
|
|
|
static listTelefones(clienteId) {
|
|
return query('SELECT * FROM cliente_telefones WHERE cliente_id = $1 ORDER BY principal DESC, id ASC', [clienteId])
|
|
}
|
|
|
|
static createTelefone({ cliente_id, tipo, numero, ramal, aceita_whatsapp, principal }) {
|
|
return execute(
|
|
`INSERT INTO cliente_telefones (cliente_id,tipo,numero,ramal,aceita_whatsapp,principal)
|
|
VALUES ($1,$2,$3,$4,$5,$6) RETURNING *`,
|
|
[cliente_id, tipo || 'celular', numero, ramal || null,
|
|
aceita_whatsapp || false, principal || false]
|
|
)
|
|
}
|
|
|
|
static updateTelefone(id, { tipo, numero, ramal, aceita_whatsapp, principal }) {
|
|
return execute(
|
|
`UPDATE cliente_telefones SET tipo=$1,numero=$2,ramal=$3,aceita_whatsapp=$4,principal=$5 WHERE id=$6`,
|
|
[tipo, numero, ramal || null, aceita_whatsapp || false, principal || false, id]
|
|
)
|
|
}
|
|
|
|
static deleteTelefone(id) {
|
|
return execute('DELETE FROM cliente_telefones WHERE id = $1', [id])
|
|
}
|
|
|
|
// ── Responsáveis ─────────────────────────────────────────
|
|
|
|
static listResponsaveis(clienteId) {
|
|
return query(
|
|
`SELECT r.*, t.numero AS telefone_numero FROM cliente_responsaveis r
|
|
LEFT JOIN cliente_telefones t ON t.id = r.telefone_id
|
|
WHERE r.cliente_id = $1 ORDER BY r.id ASC`,
|
|
[clienteId]
|
|
)
|
|
}
|
|
|
|
static createResponsavel({ cliente_id, nome, cargo, setor, telefone_id, email, permissao }) {
|
|
return execute(
|
|
`INSERT INTO cliente_responsaveis (cliente_id,nome,cargo,setor,telefone_id,email,permissao)
|
|
VALUES ($1,$2,$3,$4,$5,$6,$7) RETURNING *`,
|
|
[cliente_id, nome, cargo || null, setor || null,
|
|
telefone_id || null, email || null, permissao || null]
|
|
)
|
|
}
|
|
|
|
static updateResponsavel(id, { nome, cargo, setor, telefone_id, email, permissao }) {
|
|
return execute(
|
|
`UPDATE cliente_responsaveis SET nome=$1,cargo=$2,setor=$3,telefone_id=$4,email=$5,permissao=$6 WHERE id=$7`,
|
|
[nome, cargo || null, setor || null, telefone_id || null,
|
|
email || null, permissao || null, id]
|
|
)
|
|
}
|
|
|
|
static deleteResponsavel(id) {
|
|
return execute('DELETE FROM cliente_responsaveis WHERE id = $1', [id])
|
|
}
|
|
|
|
// ── Dados completos (cliente + endereços + telefones + responsáveis) ──────
|
|
|
|
static async findComplete(id) {
|
|
const [cliente, enderecos, telefones, responsaveis] = await Promise.all([
|
|
Cliente.findById(id),
|
|
Cliente.listEnderecos(id),
|
|
Cliente.listTelefones(id),
|
|
Cliente.listResponsaveis(id),
|
|
])
|
|
if (!cliente) return null
|
|
return { ...cliente, enderecos, telefones, responsaveis }
|
|
}
|
|
}
|
|
|
|
module.exports = Cliente
|