github.com/shoshinnikita/budget-manager@v0.7.1-0.20220131195411-8c46ff1c6778/internal/web/api/monthly_payment.go (about) 1 package api 2 3 import ( 4 "context" 5 "errors" 6 "net/http" 7 8 "github.com/ShoshinNikita/budget-manager/internal/db" 9 "github.com/ShoshinNikita/budget-manager/internal/logger" 10 "github.com/ShoshinNikita/budget-manager/internal/pkg/money" 11 "github.com/ShoshinNikita/budget-manager/internal/pkg/reqid" 12 "github.com/ShoshinNikita/budget-manager/internal/web/api/models" 13 "github.com/ShoshinNikita/budget-manager/internal/web/utils" 14 ) 15 16 type MonthlyPaymentsHandlers struct { 17 db MonthlyPaymentsDB 18 log logger.Logger 19 } 20 21 type MonthlyPaymentsDB interface { 22 AddMonthlyPayment(ctx context.Context, args db.AddMonthlyPaymentArgs) (id uint, err error) 23 EditMonthlyPayment(ctx context.Context, args db.EditMonthlyPaymentArgs) error 24 RemoveMonthlyPayment(ctx context.Context, id uint) error 25 } 26 27 // @Summary Create Monthly Payment 28 // @Tags Monthly Payments 29 // @Router /api/monthly-payments [post] 30 // @Accept json 31 // @Param body body models.AddMonthlyPaymentReq true "New Monthly Payment" 32 // @Produce json 33 // @Success 201 {object} models.AddMonthlyPaymentResp 34 // @Failure 400 {object} models.Response "Invalid request" 35 // @Failure 404 {object} models.Response "Month doesn't exist" 36 // @Failure 500 {object} models.Response "Internal error" 37 // 38 func (h MonthlyPaymentsHandlers) AddMonthlyPayment(w http.ResponseWriter, r *http.Request) { 39 ctx := r.Context() 40 log := reqid.FromContextToLogger(ctx, h.log) 41 42 // Decode 43 req := &models.AddMonthlyPaymentReq{} 44 if ok := utils.DecodeRequest(w, r, log, req); !ok { 45 return 46 } 47 log = log.WithRequest(req) 48 49 // Process 50 args := db.AddMonthlyPaymentArgs{ 51 MonthID: req.MonthID, 52 Title: req.Title, 53 TypeID: req.TypeID, 54 Notes: req.Notes, 55 Cost: money.FromFloat(req.Cost), 56 } 57 id, err := h.db.AddMonthlyPayment(ctx, args) 58 if err != nil { 59 switch { 60 case errors.Is(err, db.ErrMonthNotExist): 61 utils.EncodeError(ctx, w, log, err, http.StatusNotFound) 62 case errors.Is(err, db.ErrSpendTypeNotExist): 63 utils.EncodeError(ctx, w, log, err, http.StatusBadRequest) 64 default: 65 utils.EncodeInternalError(ctx, w, log, "couldn't add Monthly Payment", err) 66 } 67 return 68 } 69 log = log.WithField("id", id) 70 log.Debug("Monthly Payment was successfully added") 71 72 resp := &models.AddMonthlyPaymentResp{ 73 ID: id, 74 } 75 utils.Encode(ctx, w, log, utils.EncodeResponse(resp), utils.EncodeStatusCode(http.StatusCreated)) 76 } 77 78 // @Summary Edit Monthly Payment 79 // @Tags Monthly Payments 80 // @Router /api/monthly-payments [put] 81 // @Accept json 82 // @Param body body models.EditMonthlyPaymentReq true "Updated Monthly Payment" 83 // @Produce json 84 // @Success 200 {object} models.Response 85 // @Failure 400 {object} models.Response "Invalid request" 86 // @Failure 404 {object} models.Response "Monthly Payment doesn't exist" 87 // @Failure 500 {object} models.Response "Internal error" 88 // 89 func (h MonthlyPaymentsHandlers) EditMonthlyPayment(w http.ResponseWriter, r *http.Request) { 90 ctx := r.Context() 91 log := reqid.FromContextToLogger(ctx, h.log) 92 93 // Decode 94 req := &models.EditMonthlyPaymentReq{} 95 if ok := utils.DecodeRequest(w, r, log, req); !ok { 96 return 97 } 98 log = log.WithRequest(req) 99 100 // Process 101 args := db.EditMonthlyPaymentArgs{ 102 ID: req.ID, 103 Title: req.Title, 104 Notes: req.Notes, 105 TypeID: req.TypeID, 106 } 107 if req.Cost != nil { 108 cost := money.FromFloat(*req.Cost) 109 args.Cost = &cost 110 } 111 err := h.db.EditMonthlyPayment(ctx, args) 112 if err != nil { 113 switch { 114 case errors.Is(err, db.ErrMonthlyPaymentNotExist): 115 utils.EncodeError(ctx, w, log, err, http.StatusNotFound) 116 case errors.Is(err, db.ErrSpendTypeNotExist): 117 utils.EncodeError(ctx, w, log, err, http.StatusBadRequest) 118 default: 119 utils.EncodeInternalError(ctx, w, log, "couldn't edit Monthly Payment", err) 120 } 121 return 122 } 123 log.Debug("Monthly Payment was successfully edited") 124 125 utils.Encode(ctx, w, log) 126 } 127 128 // @Summary Remove Monthly Payment 129 // @Tags Monthly Payments 130 // @Router /api/monthly-payments [delete] 131 // @Accept json 132 // @Param body body models.RemoveMonthlyPaymentReq true "Monthly Payment id" 133 // @Produce json 134 // @Success 200 {object} models.Response 135 // @Failure 400 {object} models.Response "Invalid request" 136 // @Failure 404 {object} models.Response "Monthly Payment doesn't exist" 137 // @Failure 500 {object} models.Response "Internal error" 138 // 139 func (h MonthlyPaymentsHandlers) RemoveMonthlyPayment(w http.ResponseWriter, r *http.Request) { 140 ctx := r.Context() 141 log := reqid.FromContextToLogger(ctx, h.log) 142 143 // Decode 144 req := &models.RemoveMonthlyPaymentReq{} 145 if ok := utils.DecodeRequest(w, r, log, req); !ok { 146 return 147 } 148 log = log.WithRequest(req) 149 150 // Process 151 err := h.db.RemoveMonthlyPayment(ctx, req.ID) 152 if err != nil { 153 switch { 154 case errors.Is(err, db.ErrMonthlyPaymentNotExist): 155 utils.EncodeError(ctx, w, log, err, http.StatusNotFound) 156 default: 157 utils.EncodeInternalError(ctx, w, log, "couldn't remove Monthly Payment", err) 158 } 159 return 160 } 161 log.Debug("Monthly Payment was successfully removed") 162 163 utils.Encode(ctx, w, log) 164 }