feat: initial project structure (Model Project) - Backend + Multi-Frontend + Docker
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
'use strict'
|
||||
|
||||
const { execute, queryOne, query } = require('../database/postgres')
|
||||
|
||||
class Produto {
|
||||
static findById(id) {
|
||||
return queryOne(`SELECT * FROM produtos WHERE id = $1`, [id])
|
||||
}
|
||||
|
||||
static findBySku(sku, tenantId) {
|
||||
return queryOne('SELECT * FROM produtos WHERE sku = $1 AND tenant_id = $2', [sku, tenantId])
|
||||
}
|
||||
|
||||
static list(tenantId, { search, categoria, ativo, limit = 50, offset = 0 } = {}) {
|
||||
const params = [tenantId]
|
||||
let where = 'WHERE p.tenant_id = $1'
|
||||
if (ativo !== undefined) { params.push(ativo); where += ` AND p.ativo = $${params.length}` }
|
||||
if (categoria) { params.push(categoria); where += ` AND p.categoria = $${params.length}` }
|
||||
if (search) {
|
||||
params.push(`%${search.replace(/[%_]/g, '\\$&')}%`)
|
||||
where += ` AND (p.nome ILIKE $${params.length} OR p.sku ILIKE $${params.length} OR p.descricao ILIKE $${params.length})`
|
||||
}
|
||||
params.push(Math.min(Number(limit) || 50, 500))
|
||||
params.push(Math.max(Number(offset) || 0, 0))
|
||||
return query(
|
||||
`SELECT * FROM produtos p
|
||||
${where}
|
||||
ORDER BY p.nome ASC
|
||||
LIMIT $${params.length - 1} OFFSET $${params.length}`,
|
||||
params
|
||||
)
|
||||
}
|
||||
|
||||
static listCategorias(tenantId) {
|
||||
return query(
|
||||
`SELECT DISTINCT categoria FROM produtos WHERE tenant_id = $1 AND categoria IS NOT NULL ORDER BY categoria`,
|
||||
[tenantId]
|
||||
)
|
||||
}
|
||||
|
||||
static create({ tenant_id, sku, nome, descricao, unidade, preco, preco_promocional, estoque, categoria, imagem }) {
|
||||
return execute(
|
||||
`INSERT INTO produtos (tenant_id,sku,nome,descricao,unidade,preco,preco_promocional,estoque,categoria,imagem)
|
||||
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10) RETURNING *`,
|
||||
[tenant_id, sku || null, nome, descricao || null, unidade || 'un',
|
||||
preco || 0, preco_promocional || null, estoque || 0, categoria || null, imagem || null]
|
||||
)
|
||||
}
|
||||
|
||||
static update(id, { sku, nome, descricao, unidade, preco, preco_promocional, estoque, categoria, imagem, ativo }) {
|
||||
return execute(
|
||||
`UPDATE produtos SET sku=$1,nome=$2,descricao=$3,unidade=$4,preco=$5,preco_promocional=$6,
|
||||
estoque=$7,categoria=$8,imagem=$9,ativo=$10,updated_at=NOW() WHERE id=$11`,
|
||||
[sku || null, nome, descricao || null, unidade || 'un',
|
||||
preco, preco_promocional || null, estoque, categoria || null, imagem || null, ativo !== false, id]
|
||||
)
|
||||
}
|
||||
|
||||
static updateEstoque(id, estoque) {
|
||||
return execute('UPDATE produtos SET estoque=$1, updated_at=NOW() WHERE id=$2', [estoque, id])
|
||||
}
|
||||
|
||||
static updatePreco(id, preco) {
|
||||
return execute('UPDATE produtos SET preco=$1, updated_at=NOW() WHERE id=$2', [preco, id])
|
||||
}
|
||||
|
||||
static delete(id) {
|
||||
return execute('DELETE FROM produtos WHERE id = $1', [id])
|
||||
}
|
||||
|
||||
// Upsert por SKU — usado na importação CSV
|
||||
static upsertBySku({ tenant_id, sku, nome, descricao, unidade, preco, preco_promocional, estoque, categoria }) {
|
||||
return execute(
|
||||
`INSERT INTO produtos (tenant_id,sku,nome,descricao,unidade,preco,preco_promocional,estoque,categoria)
|
||||
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9)
|
||||
ON CONFLICT (sku, tenant_id) DO UPDATE
|
||||
SET nome=$3, descricao=$4, unidade=$5, preco=$6, preco_promocional=$7, estoque=$8, categoria=$9, updated_at=NOW()
|
||||
RETURNING *`,
|
||||
[tenant_id, sku, nome, descricao || null, unidade || 'un',
|
||||
preco || 0, preco_promocional || null, estoque || 0, categoria || null]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Produto
|
||||
Reference in New Issue
Block a user