feat: #44 fatura de cartão com data futura fica pendente até confirmação
- Nova tabela pending_bill_imports (migration 016) - ImportHandler.Confirm: quando is_credit_card=true e payment_date > hoje, salva como pending em vez de inserir transações - Novos endpoints: GET /pending-bills, POST /pending-bills/:id/confirm, DELETE /pending-bills/:id - Dashboard inclui pending_bill_imports no payload - Frontend: resultado "fatura salva como pendente" no ImportView - AccountsView exibe widget de faturas pendentes com ações de confirmar/descartar - dashboard_test: mock de PendingBillRepo + TransactionRepository Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
|
||||
"financeiro-carvalho/internal/service"
|
||||
)
|
||||
|
||||
type PendingBillHandler struct {
|
||||
svc *service.PendingBillService
|
||||
gameSvc *service.GameService
|
||||
}
|
||||
|
||||
func NewPendingBillHandler(svc *service.PendingBillService, gameSvc *service.GameService) *PendingBillHandler {
|
||||
return &PendingBillHandler{svc: svc, gameSvc: gameSvc}
|
||||
}
|
||||
|
||||
func (h *PendingBillHandler) List(w http.ResponseWriter, r *http.Request) {
|
||||
items, err := h.svc.List(r.Context())
|
||||
if err != nil {
|
||||
respondError(w, http.StatusInternalServerError, "failed to list pending bills")
|
||||
return
|
||||
}
|
||||
respondJSON(w, http.StatusOK, items)
|
||||
}
|
||||
|
||||
func (h *PendingBillHandler) Confirm(w http.ResponseWriter, r *http.Request) {
|
||||
id, err := strconv.Atoi(chi.URLParam(r, "id"))
|
||||
if err != nil {
|
||||
respondError(w, http.StatusBadRequest, "invalid id")
|
||||
return
|
||||
}
|
||||
if err := h.svc.Confirm(r.Context(), id); err != nil {
|
||||
if err == service.ErrPendingBillNotFound {
|
||||
respondError(w, http.StatusNotFound, "pending bill not found")
|
||||
return
|
||||
}
|
||||
respondError(w, http.StatusInternalServerError, "failed to confirm pending bill")
|
||||
return
|
||||
}
|
||||
h.gameSvc.NotifyAction(r.Context(), "import_confirmed", map[string]any{"count": 1})
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
|
||||
func (h *PendingBillHandler) Discard(w http.ResponseWriter, r *http.Request) {
|
||||
id, err := strconv.Atoi(chi.URLParam(r, "id"))
|
||||
if err != nil {
|
||||
respondError(w, http.StatusBadRequest, "invalid id")
|
||||
return
|
||||
}
|
||||
if err := h.svc.Discard(r.Context(), id); err != nil {
|
||||
respondError(w, http.StatusInternalServerError, "failed to discard pending bill")
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
Reference in New Issue
Block a user