Files
mercado.clube67.com/backend/controllers/clienteController.js
T

216 lines
6.9 KiB
JavaScript

'use strict'
const Cliente = require('../models/Cliente')
function validarCpf(cpf) {
cpf = cpf.replace(/\D/g, '')
if (cpf.length !== 11 || /^(\d)\1+$/.test(cpf)) return false
let s = 0
for (let i = 0; i < 9; i++) s += +cpf[i] * (10 - i)
let r = (s * 10) % 11; if (r === 10 || r === 11) r = 0
if (r !== +cpf[9]) return false
s = 0
for (let i = 0; i < 10; i++) s += +cpf[i] * (11 - i)
r = (s * 10) % 11; if (r === 10 || r === 11) r = 0
return r === +cpf[10]
}
function validarCnpj(cnpj) {
cnpj = cnpj.replace(/\D/g, '')
if (cnpj.length !== 14 || /^(\d)\1+$/.test(cnpj)) return false
const calc = (n) => {
let s = 0, p = n - 7
for (let i = 0; i < n; i++) { p = p < 2 ? p + 9 : p; s += +cnpj[i] * p--; }
return s % 11 < 2 ? 0 : 11 - (s % 11)
}
return calc(12) === +cnpj[12] && calc(13) === +cnpj[13]
}
const clienteController = {
async list(req, res) {
try {
const tenantId = req.tenant.id
const { search, tipo, status, limit, offset } = req.query
const rows = await Cliente.list(tenantId, { search, tipo, status, limit, offset })
res.json(rows)
} catch (err) {
console.error('[cliente.list]', err.message)
res.status(500).json({ error: 'Erro ao listar clientes' })
}
},
async get(req, res) {
try {
const cliente = await Cliente.findComplete(req.params.id)
if (!cliente) return res.status(404).json({ error: 'Cliente não encontrado' })
res.json(cliente)
} catch (err) {
console.error('[cliente.get]', err.message)
res.status(500).json({ error: 'Erro ao buscar cliente' })
}
},
async create(req, res) {
try {
const tenantId = req.tenant.id
const { tipo, nome, cpf_cnpj, email, status } = req.body
if (!tipo || !['PF', 'PJ'].includes(tipo)) return res.status(400).json({ error: 'tipo deve ser PF ou PJ' })
if (!nome?.trim()) return res.status(400).json({ error: 'nome é obrigatório' })
if (!cpf_cnpj?.trim()) return res.status(400).json({ error: 'cpf_cnpj é obrigatório' })
const doc = cpf_cnpj.replace(/\D/g, '')
if (tipo === 'PF' && !validarCpf(doc)) return res.status(400).json({ error: 'CPF inválido' })
if (tipo === 'PJ' && !validarCnpj(doc)) return res.status(400).json({ error: 'CNPJ inválido' })
const existe = await Cliente.findByCpfCnpj(doc, tenantId)
if (existe) return res.status(409).json({ error: 'CPF/CNPJ já cadastrado' })
const user_id = req.user?.id || null
const cliente = await Cliente.create({ tenant_id: tenantId, tipo, nome: nome.trim(), cpf_cnpj: doc, email, status, user_id })
res.status(201).json(cliente)
} catch (err) {
console.error('[cliente.create]', err.message)
res.status(500).json({ error: 'Erro ao criar cliente' })
}
},
async update(req, res) {
try {
const { nome, email, status } = req.body
if (!nome?.trim()) return res.status(400).json({ error: 'nome é obrigatório' })
await Cliente.update(req.params.id, { nome: nome.trim(), email, status })
res.json({ ok: true })
} catch (err) {
console.error('[cliente.update]', err.message)
res.status(500).json({ error: 'Erro ao atualizar cliente' })
}
},
async remove(req, res) {
try {
await Cliente.delete(req.params.id)
res.json({ ok: true })
} catch (err) {
console.error('[cliente.remove]', err.message)
res.status(500).json({ error: 'Erro ao remover cliente' })
}
},
// ── Endereços ─────────────────────────────────────────────
async listEnderecos(req, res) {
try {
res.json(await Cliente.listEnderecos(req.params.id))
} catch (err) {
res.status(500).json({ error: 'Erro ao listar endereços' })
}
},
async addEndereco(req, res) {
try {
const dados = { ...req.body, cliente_id: req.params.id }
const end = await Cliente.createEndereco(dados)
if (dados.principal) await Cliente.setEndereçoPrincipal(req.params.id, end.id)
res.status(201).json(end)
} catch (err) {
console.error('[cliente.addEndereco]', err.message)
res.status(500).json({ error: 'Erro ao adicionar endereço' })
}
},
async updateEndereco(req, res) {
try {
await Cliente.updateEndereco(req.params.endId, req.body)
if (req.body.principal) await Cliente.setEndereçoPrincipal(req.params.id, req.params.endId)
res.json({ ok: true })
} catch (err) {
res.status(500).json({ error: 'Erro ao atualizar endereço' })
}
},
async removeEndereco(req, res) {
try {
await Cliente.deleteEndereco(req.params.endId)
res.json({ ok: true })
} catch (err) {
res.status(500).json({ error: 'Erro ao remover endereço' })
}
},
// ── Telefones ─────────────────────────────────────────────
async listTelefones(req, res) {
try {
res.json(await Cliente.listTelefones(req.params.id))
} catch (err) {
res.status(500).json({ error: 'Erro ao listar telefones' })
}
},
async addTelefone(req, res) {
try {
const tel = await Cliente.createTelefone({ ...req.body, cliente_id: req.params.id })
res.status(201).json(tel)
} catch (err) {
res.status(500).json({ error: 'Erro ao adicionar telefone' })
}
},
async updateTelefone(req, res) {
try {
await Cliente.updateTelefone(req.params.telId, req.body)
res.json({ ok: true })
} catch (err) {
res.status(500).json({ error: 'Erro ao atualizar telefone' })
}
},
async removeTelefone(req, res) {
try {
await Cliente.deleteTelefone(req.params.telId)
res.json({ ok: true })
} catch (err) {
res.status(500).json({ error: 'Erro ao remover telefone' })
}
},
// ── Responsáveis ─────────────────────────────────────────
async listResponsaveis(req, res) {
try {
res.json(await Cliente.listResponsaveis(req.params.id))
} catch (err) {
res.status(500).json({ error: 'Erro ao listar responsáveis' })
}
},
async addResponsavel(req, res) {
try {
const r = await Cliente.createResponsavel({ ...req.body, cliente_id: req.params.id })
res.status(201).json(r)
} catch (err) {
res.status(500).json({ error: 'Erro ao adicionar responsável' })
}
},
async updateResponsavel(req, res) {
try {
await Cliente.updateResponsavel(req.params.respId, req.body)
res.json({ ok: true })
} catch (err) {
res.status(500).json({ error: 'Erro ao atualizar responsável' })
}
},
async removeResponsavel(req, res) {
try {
await Cliente.deleteResponsavel(req.params.respId)
res.json({ ok: true })
} catch (err) {
res.status(500).json({ error: 'Erro ao remover responsável' })
}
},
}
module.exports = clienteController