diff --git a/cmd/smm_core/main.go b/cmd/smm_core/main.go index eb52e5c..ab7aed8 100644 --- a/cmd/smm_core/main.go +++ b/cmd/smm_core/main.go @@ -12,6 +12,7 @@ import ( "git.3crabs.ru/save_my_money/smm_core/internal/services/budget" "git.3crabs.ru/save_my_money/smm_core/internal/services/category" "git.3crabs.ru/save_my_money/smm_core/internal/services/user" + "git.3crabs.ru/save_my_money/smm_core/internal/services/waste" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "github.com/jackc/pgx/v5/pgxpool" "google.golang.org/grpc" @@ -40,6 +41,7 @@ func main() { categoryService := category.NewCategoryService(dbpool) userService := user.NewUserService(dbpool) budgetService := budget.NewBudgetService(dbpool, categoryService) + wasteService := waste.NewWasteService(dbpool, categoryService) // Create a gRPC server object s := grpc.NewServer( @@ -69,6 +71,7 @@ func main() { categoryService, userService, budgetService, + wasteService, ), ) // Serve gRPC server diff --git a/internal/app/mappers.go b/internal/app/mappers.go index b0d132f..3d17969 100644 --- a/internal/app/mappers.go +++ b/internal/app/mappers.go @@ -4,6 +4,7 @@ import ( "git.3crabs.ru/save_my_money/smm_core/internal/services/budget" "git.3crabs.ru/save_my_money/smm_core/internal/services/category" "git.3crabs.ru/save_my_money/smm_core/internal/services/user" + "git.3crabs.ru/save_my_money/smm_core/internal/services/waste" proto "git.3crabs.ru/save_my_money/smm_core/proto" ) @@ -40,3 +41,12 @@ func mapCategories(categories []*category.CategoryEntity) []*proto.Category { } return res } + +func mapWaste(waste *waste.WasteEntity) *proto.Waste { + return &proto.Waste{ + Id: int32(waste.Id), + Name: waste.Name, + Price: int32(waste.Price), + Amount: waste.Amount, + } +} diff --git a/internal/app/server.go b/internal/app/server.go index 6f0ebf8..4c21724 100644 --- a/internal/app/server.go +++ b/internal/app/server.go @@ -6,6 +6,7 @@ import ( "git.3crabs.ru/save_my_money/smm_core/internal/services/budget" "git.3crabs.ru/save_my_money/smm_core/internal/services/category" "git.3crabs.ru/save_my_money/smm_core/internal/services/user" + "git.3crabs.ru/save_my_money/smm_core/internal/services/waste" proto "git.3crabs.ru/save_my_money/smm_core/proto" ) @@ -14,17 +15,20 @@ type Server struct { categoryService *category.CategoryService userService *user.UserService budgetService *budget.BudgetService + wasteService *waste.WasteService } func NewServer( categoryService *category.CategoryService, userService *user.UserService, budgetService *budget.BudgetService, + wasteService *waste.WasteService, ) proto.SmmCoreServer { return &Server{ categoryService: categoryService, userService: userService, budgetService: budgetService, + wasteService: wasteService, } } @@ -136,8 +140,24 @@ func (s *Server) GetBudgetCategories(ctx context.Context, req *proto.GetBudgetCa }, nil } -// AddWaste implements proto.SmmCoreServer. -func (s *Server) AddWaste(context.Context, *proto.AddWasteReq) (*proto.Waste, error) { +func (s *Server) AddWaste(ctx context.Context, req *proto.AddWasteReq) (*proto.Waste, error) { + waste, err := s.wasteService.AddWaste( + ctx, + &waste.WasteEntity{ + Name: req.Name, + Price: int(req.Price), + Amount: req.Amount, + CategoryId: int(req.CategoryId), + }, + ) + if err != nil { + return nil, err + } + return mapWaste(waste), nil +} + +// GetCategoriesStat implements proto.SmmCoreServer. +func (s *Server) GetCategoriesStat(context.Context, *proto.GetCategoriesStatReq) (*proto.CategoriesStat, error) { panic("unimplemented") } @@ -161,11 +181,6 @@ func (s *Server) GetBudgetUsers(context.Context, *proto.GetBudgetUsersReq) (*pro panic("unimplemented") } -// GetCategoriesStat implements proto.SmmCoreServer. -func (s *Server) GetCategoriesStat(context.Context, *proto.GetCategoriesStatReq) (*proto.CategoriesStat, error) { - panic("unimplemented") -} - // RemoveUserFromBudget implements proto.SmmCoreServer. func (s *Server) RemoveUserFromBudget(context.Context, *proto.RemoveUserFromBudgetReq) (*proto.Budget, error) { panic("unimplemented") diff --git a/internal/services/category/category_service.go b/internal/services/category/category_service.go index 67a64fc..bda43b5 100644 --- a/internal/services/category/category_service.go +++ b/internal/services/category/category_service.go @@ -41,3 +41,25 @@ func (s *CategoryService) AddCategory(ctx context.Context, category *CategoryEnt } return category, nil } + +func (s *CategoryService) GetCategory(ctx context.Context, categoryId int) (*CategoryEntity, error) { + query := `SELECT id, name, budget_id, favorite, monthly_limit FROM categories WHERE id = @id` + args := pgx.NamedArgs{ + "id": categoryId, + } + rows, err := s.db.Query(ctx, query, args) + if err != nil { + return nil, err + } + categories := []*CategoryEntity{} + defer rows.Close() + for rows.Next() { + category := &CategoryEntity{} + err = rows.Scan(&category.Id, &category.Name, &category.BudgetId, &category.Favorite, &category.MonthlyLimit) + if err != nil { + return nil, err + } + categories = append(categories, category) + } + return categories[0], nil +} diff --git a/internal/services/requests.restbook b/internal/services/requests.restbook index afaef27..4e715c3 100644 --- a/internal/services/requests.restbook +++ b/internal/services/requests.restbook @@ -1 +1 @@ -[{"kind":1,"language":"markdown","value":"# Добавление пользователя","outputs":[]},{"kind":2,"language":"rest-book","value":"POST http://localhost:8090/users\nauthorization: Y3JhYjpjcmFi\n\n{\n \"username\": \"foo\",\n \"password\": \"bar\"\n}","outputs":[{"mime":"x-application/rest-book","value":{"status":200,"statusText":"OK","headers":{"Date":"Mon, 25 Nov 2024 06:30:36 GMT","Content-Type":"application/json","Content-Length":"25"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","authorization":"Y3JhYjpjcmFi","User-Agent":"axios/0.21.4","Content-Length":35}},"request":{"method":"POST","httpVersion":"1.1","responseUrl":"http://localhost:8090/users","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi"},"data":{"username":"foo","password":"bar"}},"data":{"id":1,"username":"foo"}}},{"mime":"text/x-json","value":{"status":200,"statusText":"OK","headers":{"Date":"Mon, 25 Nov 2024 06:30:36 GMT","Content-Type":"application/json","Content-Length":"25"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","authorization":"Y3JhYjpjcmFi","User-Agent":"axios/0.21.4","Content-Length":35}},"request":{"method":"POST","httpVersion":"1.1","responseUrl":"http://localhost:8090/users","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi"},"data":{"username":"foo","password":"bar"}},"data":{"id":1,"username":"foo"}}},{"mime":"text/html","value":"[object Object]"}]},{"kind":1,"language":"markdown","value":"# Авторизация","outputs":[]},{"kind":2,"language":"rest-book","value":"POST http://localhost:8090/login\nauthorization: Y3JhYjpjcmFi\n\n{\n \"username\": \"foo\",\n \"password\": \"bar\"\n}","outputs":[{"mime":"x-application/rest-book","value":{"status":200,"statusText":"OK","headers":{"Date":"Sun, 24 Nov 2024 15:18:53 GMT","Content-Type":"application/json","Content-Length":"25"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","authorization":"Y3JhYjpjcmFi","User-Agent":"axios/0.21.4","Content-Length":35}},"request":{"method":"POST","httpVersion":"1.1","responseUrl":"http://localhost:8090/login","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi"},"data":{"username":"foo","password":"bar"}},"data":{"id":1,"username":"foo"}}},{"mime":"text/x-json","value":{"status":200,"statusText":"OK","headers":{"Date":"Sun, 24 Nov 2024 15:18:53 GMT","Content-Type":"application/json","Content-Length":"25"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","authorization":"Y3JhYjpjcmFi","User-Agent":"axios/0.21.4","Content-Length":35}},"request":{"method":"POST","httpVersion":"1.1","responseUrl":"http://localhost:8090/login","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi"},"data":{"username":"foo","password":"bar"}},"data":{"id":1,"username":"foo"}}},{"mime":"text/html","value":"[object Object]"}]},{"kind":1,"language":"markdown","value":"# Добавление бюджета","outputs":[]},{"kind":2,"language":"rest-book","value":"POST http://localhost:8090/budgets\nauthorization: Y3JhYjpjcmFi\nUser-Id: 1\n\n{\n \"name\": \"Семейный\"\n}","outputs":[{"mime":"x-application/rest-book","value":{"status":200,"statusText":"OK","headers":{"Date":"Mon, 25 Nov 2024 06:30:43 GMT","Content-Type":"application/json","Content-Length":"64"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","authorization":"Y3JhYjpjcmFi","User-Id":"1","User-Agent":"axios/0.21.4","Content-Length":27}},"request":{"method":"POST","httpVersion":"1.1","responseUrl":"http://localhost:8090/budgets","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi","User-Id":"1"},"data":{"name":"Семейный"}},"data":{"id":1,"name":"Семейный","startDay":0,"monthlyLimit":0}}},{"mime":"text/x-json","value":{"status":200,"statusText":"OK","headers":{"Date":"Mon, 25 Nov 2024 06:30:43 GMT","Content-Type":"application/json","Content-Length":"64"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","authorization":"Y3JhYjpjcmFi","User-Id":"1","User-Agent":"axios/0.21.4","Content-Length":27}},"request":{"method":"POST","httpVersion":"1.1","responseUrl":"http://localhost:8090/budgets","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi","User-Id":"1"},"data":{"name":"Семейный"}},"data":{"id":1,"name":"Семейный","startDay":0,"monthlyLimit":0}}},{"mime":"text/html","value":"[object Object]"}]},{"kind":1,"language":"markdown","value":"# Запрос бюджетов","outputs":[]},{"kind":2,"language":"rest-book","value":"GET http://localhost:8090/budgets\nauthorization: Y3JhYjpjcmFi\nUser-Id: 1","outputs":[{"mime":"x-application/rest-book","value":{"status":200,"statusText":"OK","headers":{"Date":"Mon, 25 Nov 2024 06:34:50 GMT","Content-Type":"application/json","Content-Length":"272"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","authorization":"Y3JhYjpjcmFi","User-Id":"1","User-Agent":"axios/0.21.4"}},"request":{"method":"GET","httpVersion":"1.1","responseUrl":"http://localhost:8090/budgets","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi","User-Id":"1"}},"data":{"budgets":[{"id":1,"name":"Семейный","startDay":0,"monthlyLimit":0,"categories":[{"id":1,"name":"Транспорт","budgetId":0,"favorite":false,"monthlyLimit":0},{"id":2,"name":"Продукты","budgetId":0,"favorite":false,"monthlyLimit":0}]}]}}},{"mime":"text/x-json","value":{"status":200,"statusText":"OK","headers":{"Date":"Mon, 25 Nov 2024 06:34:50 GMT","Content-Type":"application/json","Content-Length":"272"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","authorization":"Y3JhYjpjcmFi","User-Id":"1","User-Agent":"axios/0.21.4"}},"request":{"method":"GET","httpVersion":"1.1","responseUrl":"http://localhost:8090/budgets","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi","User-Id":"1"}},"data":{"budgets":[{"id":1,"name":"Семейный","startDay":0,"monthlyLimit":0,"categories":[{"id":1,"name":"Транспорт","budgetId":0,"favorite":false,"monthlyLimit":0},{"id":2,"name":"Продукты","budgetId":0,"favorite":false,"monthlyLimit":0}]}]}}},{"mime":"text/html","value":"[object Object]"}]},{"kind":1,"language":"markdown","value":"# Добавление пользователя в бюджет","outputs":[]},{"kind":2,"language":"rest-book","value":"PUT http://localhost:8090/budgets/1/users\nauthorization: Y3JhYjpjcmFi\nUser-Id: 1\n\n{\n \"user_id\": \"2\"\n}","outputs":[{"mime":"x-application/rest-book","value":{"status":200,"statusText":"OK","headers":{"Date":"Sun, 24 Nov 2024 15:21:36 GMT","Content-Type":"application/json","Content-Length":"2"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","authorization":"Y3JhYjpjcmFi","User-Id":"1","User-Agent":"axios/0.21.4","Content-Length":15}},"request":{"method":"PUT","httpVersion":"1.1","responseUrl":"http://localhost:8090/budgets/1/users","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi","User-Id":"1"},"data":{"user_id":"2"}},"data":{}}},{"mime":"text/x-json","value":{"status":200,"statusText":"OK","headers":{"Date":"Sun, 24 Nov 2024 15:21:36 GMT","Content-Type":"application/json","Content-Length":"2"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","authorization":"Y3JhYjpjcmFi","User-Id":"1","User-Agent":"axios/0.21.4","Content-Length":15}},"request":{"method":"PUT","httpVersion":"1.1","responseUrl":"http://localhost:8090/budgets/1/users","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi","User-Id":"1"},"data":{"user_id":"2"}},"data":{}}},{"mime":"text/html","value":"[object Object]"}]}] \ No newline at end of file +[{"kind":1,"language":"markdown","value":"# Добавление пользователя","outputs":[]},{"kind":2,"language":"rest-book","value":"POST http://localhost:8090/users\nauthorization: Y3JhYjpjcmFi\n\n{\n \"username\": \"foo\",\n \"password\": \"bar\"\n}","outputs":[{"mime":"x-application/rest-book","value":{"status":200,"statusText":"OK","headers":{"Date":"Mon, 25 Nov 2024 09:33:47 GMT","Content-Type":"application/json","Content-Length":"25"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","authorization":"Y3JhYjpjcmFi","User-Agent":"axios/0.21.4","Content-Length":35}},"request":{"method":"POST","httpVersion":"1.1","responseUrl":"http://localhost:8090/users","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi"},"data":{"username":"foo","password":"bar"}},"data":{"id":1,"username":"foo"}}},{"mime":"text/x-json","value":{"status":200,"statusText":"OK","headers":{"Date":"Mon, 25 Nov 2024 09:33:47 GMT","Content-Type":"application/json","Content-Length":"25"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","authorization":"Y3JhYjpjcmFi","User-Agent":"axios/0.21.4","Content-Length":35}},"request":{"method":"POST","httpVersion":"1.1","responseUrl":"http://localhost:8090/users","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi"},"data":{"username":"foo","password":"bar"}},"data":{"id":1,"username":"foo"}}},{"mime":"text/html","value":"[object Object]"}]},{"kind":1,"language":"markdown","value":"# Авторизация","outputs":[]},{"kind":2,"language":"rest-book","value":"POST http://localhost:8090/login\nauthorization: Y3JhYjpjcmFi\n\n{\n \"username\": \"foo\",\n \"password\": \"bar\"\n}","outputs":[{"mime":"x-application/rest-book","value":{"status":200,"statusText":"OK","headers":{"Date":"Sun, 24 Nov 2024 15:18:53 GMT","Content-Type":"application/json","Content-Length":"25"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","authorization":"Y3JhYjpjcmFi","User-Agent":"axios/0.21.4","Content-Length":35}},"request":{"method":"POST","httpVersion":"1.1","responseUrl":"http://localhost:8090/login","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi"},"data":{"username":"foo","password":"bar"}},"data":{"id":1,"username":"foo"}}},{"mime":"text/x-json","value":{"status":200,"statusText":"OK","headers":{"Date":"Sun, 24 Nov 2024 15:18:53 GMT","Content-Type":"application/json","Content-Length":"25"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","authorization":"Y3JhYjpjcmFi","User-Agent":"axios/0.21.4","Content-Length":35}},"request":{"method":"POST","httpVersion":"1.1","responseUrl":"http://localhost:8090/login","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi"},"data":{"username":"foo","password":"bar"}},"data":{"id":1,"username":"foo"}}},{"mime":"text/html","value":"[object Object]"}]},{"kind":1,"language":"markdown","value":"# Добавление бюджета","outputs":[]},{"kind":2,"language":"rest-book","value":"POST http://localhost:8090/budgets\nauthorization: Y3JhYjpjcmFi\nUser-Id: 1\n\n{\n \"name\": \"Семейный\"\n}","outputs":[{"mime":"x-application/rest-book","value":{"status":200,"statusText":"OK","headers":{"Date":"Mon, 25 Nov 2024 09:33:52 GMT","Content-Type":"application/json","Content-Length":"80"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","authorization":"Y3JhYjpjcmFi","User-Id":"1","User-Agent":"axios/0.21.4","Content-Length":27}},"request":{"method":"POST","httpVersion":"1.1","responseUrl":"http://localhost:8090/budgets","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi","User-Id":"1"},"data":{"name":"Семейный"}},"data":{"id":1,"name":"Семейный","startDay":0,"monthlyLimit":0,"categories":[]}}},{"mime":"text/x-json","value":{"status":200,"statusText":"OK","headers":{"Date":"Mon, 25 Nov 2024 09:33:52 GMT","Content-Type":"application/json","Content-Length":"80"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","authorization":"Y3JhYjpjcmFi","User-Id":"1","User-Agent":"axios/0.21.4","Content-Length":27}},"request":{"method":"POST","httpVersion":"1.1","responseUrl":"http://localhost:8090/budgets","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi","User-Id":"1"},"data":{"name":"Семейный"}},"data":{"id":1,"name":"Семейный","startDay":0,"monthlyLimit":0,"categories":[]}}},{"mime":"text/html","value":"[object Object]"}]},{"kind":1,"language":"markdown","value":"# Запрос бюджетов","outputs":[]},{"kind":2,"language":"rest-book","value":"GET http://localhost:8090/budgets\nauthorization: Y3JhYjpjcmFi\nUser-Id: 1","outputs":[{"mime":"x-application/rest-book","value":{"status":200,"statusText":"OK","headers":{"Date":"Mon, 25 Nov 2024 09:33:56 GMT","Content-Type":"application/json","Content-Length":"259"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","authorization":"Y3JhYjpjcmFi","User-Id":"1","User-Agent":"axios/0.21.4"}},"request":{"method":"GET","httpVersion":"1.1","responseUrl":"http://localhost:8090/budgets","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi","User-Id":"1"}},"data":{"budgets":[{"id":1,"name":"Семейный","startDay":0,"monthlyLimit":0,"categories":[{"id":1,"name":"Транспорт","budgetId":0,"favorite":false,"monthlyLimit":0},{"id":2,"name":"Продукты","budgetId":0,"favorite":false,"monthlyLimit":0}]}]}}},{"mime":"text/x-json","value":{"status":200,"statusText":"OK","headers":{"Date":"Mon, 25 Nov 2024 09:33:56 GMT","Content-Type":"application/json","Content-Length":"259"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","authorization":"Y3JhYjpjcmFi","User-Id":"1","User-Agent":"axios/0.21.4"}},"request":{"method":"GET","httpVersion":"1.1","responseUrl":"http://localhost:8090/budgets","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi","User-Id":"1"}},"data":{"budgets":[{"id":1,"name":"Семейный","startDay":0,"monthlyLimit":0,"categories":[{"id":1,"name":"Транспорт","budgetId":0,"favorite":false,"monthlyLimit":0},{"id":2,"name":"Продукты","budgetId":0,"favorite":false,"monthlyLimit":0}]}]}}},{"mime":"text/html","value":"[object Object]"}]},{"kind":1,"language":"markdown","value":"# Добавление пользователя в бюджет","outputs":[]},{"kind":2,"language":"rest-book","value":"PUT http://localhost:8090/budgets/1/users\nauthorization: Y3JhYjpjcmFi\nUser-Id: 1\n\n{\n \"user_id\": \"2\"\n}","outputs":[{"mime":"x-application/rest-book","value":{"status":200,"statusText":"OK","headers":{"Date":"Sun, 24 Nov 2024 15:21:36 GMT","Content-Type":"application/json","Content-Length":"2"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","authorization":"Y3JhYjpjcmFi","User-Id":"1","User-Agent":"axios/0.21.4","Content-Length":15}},"request":{"method":"PUT","httpVersion":"1.1","responseUrl":"http://localhost:8090/budgets/1/users","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi","User-Id":"1"},"data":{"user_id":"2"}},"data":{}}},{"mime":"text/x-json","value":{"status":200,"statusText":"OK","headers":{"Date":"Sun, 24 Nov 2024 15:21:36 GMT","Content-Type":"application/json","Content-Length":"2"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","authorization":"Y3JhYjpjcmFi","User-Id":"1","User-Agent":"axios/0.21.4","Content-Length":15}},"request":{"method":"PUT","httpVersion":"1.1","responseUrl":"http://localhost:8090/budgets/1/users","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi","User-Id":"1"},"data":{"user_id":"2"}},"data":{}}},{"mime":"text/html","value":"[object Object]"}]},{"kind":1,"language":"markdown","value":"# Добавление траты","outputs":[]},{"kind":2,"language":"rest-book","value":"POST http://localhost:8090/wastes\nauthorization: Y3JhYjpjcmFi\nUser-Id: 1\n\n{\n \"name\": \"Молоко\",\n \"price\": 10000,\n \"amount\": 1,\n \"category_id\": 1\n}","outputs":[{"mime":"x-application/rest-book","value":{"status":200,"statusText":"OK","headers":{"Date":"Mon, 25 Nov 2024 09:36:48 GMT","Content-Type":"application/json","Content-Length":"55"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","authorization":"Y3JhYjpjcmFi","User-Id":"1","User-Agent":"axios/0.21.4","Content-Length":64}},"request":{"method":"POST","httpVersion":"1.1","responseUrl":"http://localhost:8090/wastes","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi","User-Id":"1"},"data":{"name":"Молоко","price":10000,"amount":1,"category_id":1}},"data":{"id":3,"name":"Молоко","price":10000,"amount":1}}},{"mime":"text/x-json","value":{"status":200,"statusText":"OK","headers":{"Date":"Mon, 25 Nov 2024 09:36:48 GMT","Content-Type":"application/json","Content-Length":"55"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","authorization":"Y3JhYjpjcmFi","User-Id":"1","User-Agent":"axios/0.21.4","Content-Length":64}},"request":{"method":"POST","httpVersion":"1.1","responseUrl":"http://localhost:8090/wastes","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi","User-Id":"1"},"data":{"name":"Молоко","price":10000,"amount":1,"category_id":1}},"data":{"id":3,"name":"Молоко","price":10000,"amount":1}}},{"mime":"text/html","value":"[object Object]"}]}] \ No newline at end of file diff --git a/internal/services/waste/waste_service.go b/internal/services/waste/waste_service.go new file mode 100644 index 0000000..bc854e1 --- /dev/null +++ b/internal/services/waste/waste_service.go @@ -0,0 +1,54 @@ +package waste + +import ( + "context" + "fmt" + + "git.3crabs.ru/save_my_money/smm_core/internal/services/category" + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgxpool" +) + +type WasteEntity struct { + Id int + Name string + Price int + Amount float32 + BudgetId int + CategoryId int +} + +type WasteService struct { + db *pgxpool.Pool + categoryService *category.CategoryService +} + +func NewWasteService( + db *pgxpool.Pool, + categoryService *category.CategoryService, +) *WasteService { + return &WasteService{ + db: db, + categoryService: categoryService, + } +} + +func (s *WasteService) AddWaste(ctx context.Context, waste *WasteEntity) (*WasteEntity, error) { + category, err := s.categoryService.GetCategory(ctx, waste.CategoryId) + if err != nil { + return nil, err + } + + query := `INSERT INTO wastes (name, price, amount, budget_id, category_id) VALUES (@name, @price, @amount, @budget_id, @category_id) RETURNING id` + args := pgx.NamedArgs{ + "name": waste.Name, + "price": waste.Price, + "amount": waste.Amount, + "budget_id": category.BudgetId, + "category_id": waste.CategoryId, + } + if err := s.db.QueryRow(ctx, query, args).Scan(&waste.Id); err != nil { + return nil, fmt.Errorf("unable to insert row: %w", err) + } + return waste, nil +} diff --git a/migrations/20241120174237_add_positions_table.sql b/migrations/20241120174237_add_wastes_table.sql similarity index 100% rename from migrations/20241120174237_add_positions_table.sql rename to migrations/20241120174237_add_wastes_table.sql