feat: initial project structure (Model Project) - Backend + Multi-Frontend + Docker
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
'use strict'
|
||||
|
||||
const { query } = require('../database/postgres')
|
||||
|
||||
function tFilter(tenantId, alias = 't') {
|
||||
if (!tenantId) return ''
|
||||
const id = parseInt(tenantId, 10)
|
||||
if (!Number.isInteger(id) || id <= 0) throw new Error('tenantId inválido')
|
||||
return `AND ${alias}.tenant_id = ${id}`
|
||||
}
|
||||
|
||||
class Analytics {
|
||||
static async getRevenueStats(raffle_id = null, tenantId = null) {
|
||||
const raffleFilter = raffle_id ? `AND r.id = $1` : ''
|
||||
const tenantFilter = tenantId ? `AND t.tenant_id = ${parseInt(tenantId)}` : ''
|
||||
const params = raffle_id ? [raffle_id] : []
|
||||
|
||||
const sql = `
|
||||
SELECT
|
||||
COALESCE(SUM(t.price_paid), 0) AS total_revenue,
|
||||
COALESCE(AVG(t.price_paid), 0) AS avg_price,
|
||||
COUNT(t.id) AS total_tickets_sold
|
||||
FROM tickets t
|
||||
JOIN raffles r ON r.id = t.raffle_id
|
||||
WHERE t.status = 'sold' ${raffleFilter} ${tenantFilter}
|
||||
`
|
||||
const res = await query(sql, params)
|
||||
const row = res[0] || { total_revenue: 0, avg_price: 0, total_tickets_sold: 0 }
|
||||
|
||||
const tWhere = tenantId ? `WHERE tenant_id = ${parseInt(tenantId, 10)}` : ''
|
||||
const [usersRow] = await query(`SELECT COUNT(*) AS cnt FROM users ${tWhere}`)
|
||||
const [activeRow] = await query(
|
||||
tenantId
|
||||
? `SELECT COUNT(t.id) AS cnt FROM tickets t JOIN raffles r ON r.id = t.raffle_id WHERE r.tenant_id = ${parseInt(tenantId, 10)} AND t.status = 'sold'`
|
||||
: `SELECT COUNT(*) AS cnt FROM tickets WHERE status = 'sold'`
|
||||
)
|
||||
|
||||
row.total_users = usersRow?.cnt ?? 0
|
||||
row.active_tickets = activeRow?.cnt ?? 0
|
||||
return row
|
||||
}
|
||||
|
||||
static getSalesByDay(tenantId = null) {
|
||||
const f = tFilter(tenantId)
|
||||
return query(`
|
||||
SELECT
|
||||
DATE(t.data_compra) AS date,
|
||||
COUNT(t.id) AS tickets_sold,
|
||||
SUM(t.price_paid) AS revenue
|
||||
FROM tickets t
|
||||
WHERE t.data_compra >= NOW() - INTERVAL '30 days' AND t.status = 'sold' ${f}
|
||||
GROUP BY date
|
||||
ORDER BY date ASC
|
||||
`)
|
||||
}
|
||||
|
||||
static getSalesByHour(tenantId = null) {
|
||||
const f = tFilter(tenantId)
|
||||
return query(`
|
||||
SELECT
|
||||
EXTRACT(HOUR FROM t.data_compra) AS hour_of_day,
|
||||
COUNT(t.id) AS tickets_sold,
|
||||
COALESCE(SUM(t.price_paid), 0) AS revenue
|
||||
FROM tickets t
|
||||
WHERE t.data_compra >= NOW() - INTERVAL '7 days' AND t.status = 'sold' ${f}
|
||||
GROUP BY hour_of_day
|
||||
ORDER BY hour_of_day ASC
|
||||
`)
|
||||
}
|
||||
|
||||
static getSalesByRaffle(tenantId = null) {
|
||||
const f = tenantId ? `AND r.tenant_id = ${parseInt(tenantId)}` : ''
|
||||
return query(`
|
||||
SELECT
|
||||
r.id AS raffle_id,
|
||||
r.titulo AS raffle_name,
|
||||
COUNT(t.id) AS tickets_sold,
|
||||
r.total_numeros,
|
||||
COALESCE(SUM(t.price_paid), 0) AS revenue
|
||||
FROM raffles r
|
||||
LEFT JOIN tickets t ON t.raffle_id = r.id AND t.status = 'sold'
|
||||
WHERE r.ativo = 1 ${f}
|
||||
GROUP BY r.id, r.titulo, r.total_numeros
|
||||
ORDER BY tickets_sold DESC
|
||||
`)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Analytics
|
||||
Reference in New Issue
Block a user