Add temporary manual financial release

This commit is contained in:
Tiago
2026-09-29 13:16:18 -03:00
parent 75e56ebd05
commit 93d658cd70
6 changed files with 66 additions and 23 deletions
@@ -4,6 +4,7 @@ import com.seconectai.condocontab.config.DataSourceProvider;
import java.sql.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
public final class BloqueioJob implements Runnable {
private final DataSourceProvider ds;
@@ -29,7 +30,7 @@ public final class BloqueioJob implements Runnable {
long emp = rs.getLong(1);
long per = periodo(c, emp);
PeriodoStatus st = status(c, per);
if (LocalDate.now().isAfter(st.dataVencimento()) && !"pago".equals(st.status())) {
if (LocalDate.now().isAfter(st.dataVencimento()) && !"pago".equals(st.status()) && !st.temLiberacaoTemporariaValida()) {
try (PreparedStatement u = c.prepareStatement("UPDATE periodos_uso SET status='bloqueado', data_bloqueio=now() WHERE id=?; UPDATE empresas SET status='bloqueada' WHERE id=?")) {
u.setLong(1, per);
u.setLong(2, emp);
@@ -83,14 +84,19 @@ public final class BloqueioJob implements Runnable {
}
private PeriodoStatus status(Connection c, long id) throws SQLException {
try (PreparedStatement ps = c.prepareStatement("SELECT status,data_vencimento FROM periodos_uso WHERE id=?")) {
try (PreparedStatement ps = c.prepareStatement("SELECT status,data_vencimento,liberacao_temporaria_ate FROM periodos_uso WHERE id=?")) {
ps.setLong(1, id);
try (ResultSet rs = ps.executeQuery()) {
rs.next();
return new PeriodoStatus(rs.getString(1), rs.getDate(2).toLocalDate());
Timestamp ate = rs.getTimestamp(3);
return new PeriodoStatus(rs.getString(1), rs.getDate(2).toLocalDate(), ate == null ? null : ate.toLocalDateTime());
}
}
}
private record PeriodoStatus(String status, LocalDate dataVencimento) {}
private record PeriodoStatus(String status, LocalDate dataVencimento, LocalDateTime liberacaoTemporariaAte) {
boolean temLiberacaoTemporariaValida() {
return liberacaoTemporariaAte != null && LocalDateTime.now().isBefore(liberacaoTemporariaAte);
}
}
}
@@ -440,17 +440,9 @@ public final class MasterHandlers implements HttpHandler {
HttpResponses.json(ex, 404, Map.of("erro", "empresa_nao_encontrada"));
return;
}
long periodoId = periodoAtual(conn, empresaId);
try (PreparedStatement ps = conn.prepareStatement("UPDATE periodos_uso SET status='pago', data_liberacao=now(), data_bloqueio=NULL WHERE id=?")) {
ps.setLong(1, periodoId);
ps.executeUpdate();
}
try (PreparedStatement ps = conn.prepareStatement("UPDATE empresas SET status='ativa' WHERE id=?")) {
ps.setLong(1, empresaId);
ps.executeUpdate();
}
long periodoId = liberarTemporariamente(conn, empresaId);
conn.commit();
HttpResponses.json(ex, 200, Map.of("ok", true, "empresa_id", empresaId, "periodo_uso_id", periodoId, "status", "ativa", "liberacao", "manual"));
HttpResponses.json(ex, 200, Map.of("ok", true, "empresa_id", empresaId, "periodo_uso_id", periodoId, "status", "ativa", "liberacao", "temporaria", "dias", 3));
} catch (Exception e) {
conn.rollback();
throw e;
@@ -467,14 +459,54 @@ public final class MasterHandlers implements HttpHandler {
HttpResponses.json(ex, 400, Map.of("erro", "status_invalido"));
return;
}
try (Connection conn = dataSourceProvider.getMasterConnection(); PreparedStatement ps = conn.prepareStatement("UPDATE empresas SET status=? WHERE id=? AND status<>'excluida'")) {
ps.setString(1, status);
ps.setLong(2, empresaId);
if (ps.executeUpdate() == 0) { HttpResponses.json(ex, 404, Map.of("erro", "empresa_nao_encontrada")); return; }
HttpResponses.json(ex, 200, Map.of("ok", true, "empresa_id", empresaId, "status", status));
try (Connection conn = dataSourceProvider.getMasterConnection()) {
conn.setAutoCommit(false);
try {
if (!exists(conn, "SELECT 1 FROM empresas WHERE id=? AND status<>'excluida'", empresaId)) {
conn.rollback();
HttpResponses.json(ex, 404, Map.of("erro", "empresa_nao_encontrada"));
return;
}
if ("ativa".equals(status)) {
long periodoId = liberarTemporariamente(conn, empresaId);
conn.commit();
HttpResponses.json(ex, 200, Map.of("ok", true, "empresa_id", empresaId, "periodo_uso_id", periodoId, "status", status, "liberacao", "temporaria", "dias", 3));
return;
}
long periodoId = periodoAtual(conn, empresaId);
try (PreparedStatement ps = conn.prepareStatement("UPDATE periodos_uso SET status='bloqueado', data_bloqueio=now(), liberacao_temporaria_ate=NULL, liberacao_temporaria_motivo=NULL WHERE id=?")) {
ps.setLong(1, periodoId);
ps.executeUpdate();
}
try (PreparedStatement ps = conn.prepareStatement("UPDATE empresas SET status='bloqueada' WHERE id=?")) {
ps.setLong(1, empresaId);
ps.executeUpdate();
}
conn.commit();
HttpResponses.json(ex, 200, Map.of("ok", true, "empresa_id", empresaId, "status", status));
} catch (Exception err) {
conn.rollback();
throw err;
} finally {
conn.setAutoCommit(true);
}
}
}
private long liberarTemporariamente(Connection conn, long empresaId) throws SQLException {
long periodoId = periodoAtual(conn, empresaId);
try (PreparedStatement ps = conn.prepareStatement("UPDATE periodos_uso SET status='pendente', data_liberacao=now(), data_bloqueio=NULL, liberacao_temporaria_ate=now() + interval '3 days', liberacao_temporaria_motivo='Liberacao manual do Master' WHERE id=?")) {
ps.setLong(1, periodoId);
ps.executeUpdate();
}
try (PreparedStatement ps = conn.prepareStatement("UPDATE empresas SET status='ativa' WHERE id=?")) {
ps.setLong(1, empresaId);
ps.executeUpdate();
}
return periodoId;
}
private void registrarLembrete(HttpExchange ex, long empresaId) throws Exception {
Map<String,String> b=body(ex); String canal=required(b,"canal");
try(Connection conn=dataSourceProvider.getMasterConnection()){