90 lines
3.0 KiB
JavaScript
90 lines
3.0 KiB
JavaScript
'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
|